【Spring 從0開始】JdbcTemplate 資料庫事務管理
阿新 • • 發佈:2021-08-07
現在有個賬戶表,裡面存著使用者金額。
如果要真正地做好轉賬的操作,就要用到事務,否則當出現異常後會出現數據不一致等問題。
try {
// 第一步 開啟事務
// 第二步 進行業務操作
// 第三步 沒有發生異常,提交事務
} catch(){
// 第四步 發生異常,事務回滾
}
一、spring 中的事務管理
通常,把事務加在 service 層(業務邏輯層)。
而在 spring 中管理事務可以有 2 種方式實現:
- 程式設計式管理:就像上面虛擬碼那樣,這種使用起來不方便。
- 宣告式管理:通過配置方式實現,推薦使用。其中,可以基於 XML 方式進行配置,也可以基於註解,顯然後者更方便。
在 spring 中進行宣告式事務管理,底層使用的是 AOP 原理。
二、spring 事務管理 API
spring 提供了一個介面 PlatformTransactionManager ,代表事務管理器。此介面針對不同的框架提供不同的實現類。
利用idea工具,展開結構,使用 jdbcTemplate 用到的是 DataSourceTransactionManager 。
三、使用事務管理
1. 配置檔案
建立事務管理器。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入資料來源--> <property name="dataSource" ref="dataSource"></property> </bean>
開啟事務註解,使用名稱空間 tx
。
<!--開啟事務註釋-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
2. 類上新增事務註解
註解 @Transactional 可以加在 service 類上,也可以加到方法上:
- 加到類上,表示類下所有的方法都添加了事務。
- 加到方法,表示只有該方法新增事務。
@Service @Transactional public class UserService { @Autowired private UserDao userDao; // 轉賬方法 public void accountMoney() { // 大周 少 100 userDao.reduceMoney(); // 模擬異常 int i = 1/0; // 小毛 加 100 userDao.addMoney(); } }
介面實現類 UserDaoImpl 。
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void addMoney() {
String sql = "update t_account set money=money+? where username=?";
jdbcTemplate.update(sql, 100, "小毛");
}
@Override
public void reduceMoney() {
String sql = "update t_account set money=money-? where username=?";
jdbcTemplate.update(sql, 100, "大周");
}
}
到測試類裡執行一下:
public class TestTrans {
@Test
public void testJdbc() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.accountMoney();
}
}
注意,上面的 service 裡我手動添加了異常,所以執行後,事務應該是要回滾操作,2 個人的金額仍然各是 1000 。
八月 07, 2021 10:39:57 上午 com.alibaba.druid.pool.DruidDataSource info
資訊: {dataSource-1} inited
java.lang.ArithmeticException: / by zero
重新整理資料表。
現在我去掉 service 類中的異常 int i = 1/0;
,重新執行測試方法:
八月 07, 2021 10:47:01 上午 com.alibaba.druid.pool.DruidDataSource info
資訊: {dataSource-1} inited
Process finished with exit code 0
重新整理資料表。
結果正確。
--不要用肉體的勤奮,去掩蓋思考的懶惰--