本文共 2141 字,大约阅读时间需要 7 分钟。
事务是指逻辑上的一组操作,要么全部成功,要么全部失败;
例如:peter给sam转账一万元,peter的账户要减少一万元,Sam的账户要增加一万元。这个操作过程要么全部成功,要么全部失败,不能出现peter转账后自己账户减少了一万元,而Sam账户却存款金额却没有增加,这一组操作是一个完整的整体,要一次性完成,即使中间发生意外,也要执行完整,要么执行成功,要么执行失败回到转账之前的账户状态,也就是回到起点。不难看出,事务是一个整体,我们可以把这个性质叫做事务的原子性。
说到事务的原子性,不得不说事务的四个性质。
事务的四个性质:原子性,一致性,隔离性,持久性。
原子性:事务是一个不可分割的单位,事务中的操作要么都发生,要么都不发生。
一致性:事务执行前后数据的完整性要保持一致。
隔离性:多用户并发访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发事务之间数据要相互隔离。
持久性:是指一个事务一旦被提交,他对数据库中数据的改变是永久性的,即使数据库发生故障也不应该对其他有任何影响。
(链接)
在Spring中,支持两种方式的事务管理:编程式事务管理和声明式事务管理。
(1)编程式事务管理 是通过TransactionTemplate手动管理事务,在实际应用中很少使用;
(2)声明式事务管理 是使用XML配置声明式事物,并通过AOP实现声明式事务,是一种面向切面的开发,在开发中推荐使用,是因为这种方式事务管理代码侵入性最小(这里可以把代码侵入性最小理解为模块化,松散耦合)
在Spring中提供了一组接口完成对事务的管理。其中,事务管理高层抽象主要包括3个接口:
接口之间并非独立存在,相互之间有一定的联系,比如,事务定义的隔离级别和传播行为需要通过平台事务管理器来管理事务并加以实现。
Spring为不同的持久化框架提供了不同的PlatformTransactionManager接口实现,如下图所示不通持久层对应的不同PlatformTransactionManager接口
事务的其中一个特性:隔离性,是指不同事务并发执行,互不干扰。
如果不考虑事务的隔离,将造成一些安全问题:数据的脏读、不可重复读、幻读或虚读。而隔离级别就是用来解决这一类问题。
脏读:一个事务读取了另一个事务改写但未提交的数据,如果这些数据被回滚,则读到的数据时无效的。
不可重复读:在同一个事务中,多次读取同一个数据返回的结果有所不同。
幻读(虚读):一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了,再后来的查询中,第一个事务就会发现有些原来没有的记录。
事务的四种隔离级别:
TransactionDefinition事务定义传播行为
解释例子:
如果出现一种复杂的情况:一个业务的完成需要调用Service1.aaa()和Service2中的bbb(),那么就需要用到事务的传播行为来解决业务层方法之间的相互调用问题。
结合上图中的复杂事务说明情况,当要完成这个复杂的业务的时候,先调用aaa(),后调用bbb();
第一类:
Propagation_REQUIRED:如果aaa()当中有事务,bbb()就用aaa()中的事务;如果aaa()中没有事务,则创建一个事务,bbb()可以使用该事务,保证两个操作都在同一个事务中。
Propagation_SUPPORTS:如果aaa()当中没有事务,bbb()就不使用事务。
Propagation_MANDATORY:如果aaa()当中没有事务,直接抛出异常。
第二类:
Propagation_REQUIRES_NEW:如果aaa()当中有事务,则挂起当前事务,并创建一个新事务。保证两个方法操作不再同一个事务中。
Propagation_NOT_SUPPORTED:(非事务方式)如果aaa()当中有事务,则挂起当前事务,执行bbb()。
Propagation_NEVER:这种方式总是以非事务方式运行,如果存在事务,则抛出异常。
第三类:
Propagation_NESTED:如果aaa()中有事务,则设置保存点,对事务就行嵌套执行bbb,如果bbb中发生异常,则根据bbb中的事务设定可抛出异常或者回滚到保存点等,如果执行成功,两者最后同时提交。
利用事务平台管理器定义隔离级别、传播行为来管理事务,中间产生的保存点、新事物标志性信息等状态,都保存在TransactionStatus对象里面。
下一篇:是对Spring事物管理的详细应用。