基于Spring JDBC的事务处理
事务(Transaction):在数据库中,可以保持一系列的数据操作要么全部执行成功,要么全部执行失败的机制!
假设存在以下信息:
账户 | 余额 |
---|---|
阿三 | 1000 |
王五 | 8000 |
如果存在任务“王五向阿三转账5000元”,需要执行的SQL语句大致是:
代码语言:javascript复制update 账户信息表 set 余额=余额-5000 where 账户='王五';
update 账户信息表 set 余额=余额 5000 where 账户='阿三';
如果出现某种意外,导致以上第1条SQL语句成功执行了,第2条却无法执行或执行失败,就会出现数据安全问题(当然,把以上2条SQL语句的执行顺序对调后,出现以上状态也是不安全的)。
在以上这种“转账”的任务中,如果2条SQL语句都执行成功,就是预期的效果,但是,即使是2条SQL语句都执行失败了,数据安全也不会受到影响,也属于是可以接受的。
在基于Spring JDBC的编程中,只需要为业务方法加上@Transactional
注解,就可以使得该业务方法中的多条数据操作是有事务的保障的,这多条数据操作要么全部成功,要么全部失败,不会出现成功一半且失败一半的问题!
框架在处理“事务”时,其大致的执行方式是:
代码语言:javascript复制try {
开启事务(BEGIN)
执行一系列的数据操作
提交事务(COMMIT)
} catch (RuntimeException e) {
回滚事务(ROLLBACK)
}
所以,在基于Spring JDBC的编程中,需要注意:
- 如果某个业务涉及2次或2次以上的增删改(例如2次
UPDATE
操作,或1次INSERT
与1次DELETE
,或其它)操作,必须在业务方法的声明之前添加@Transactional
注解,以使得该业务的执行过程中是有事务的保障的; - 在调用持久层的增删改操作时,必须及时获取返回的受影响行数,并判断受影响行数是否是预期值,如果不是,必须抛出
RuntimeException
或其子孙类异常!
另外,@Transactional
注解还可以添加在业务类的声明之前,则当前业务类中所有业务方法都是有事务保障的,但是,通常没有这个必要性,所以,并不推荐这样使用!
课后,可自行了解:事务的ACID特性,事务的传播,事务的隔离。