大家好,欢迎来到IT知识分享网。
一、事务介绍
使用MySQL的事务功能,就要求MySQL的表引擎类型为Innodb才支持事务。否则,在Java程序中做了commit或rollback,但在数据库中根本不能生效。
原子性:指整个事务是不可以分割的工作单元。只有事务中所有的操作执行成功,才算整个事务成功,事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该回到执行事务前的状态。
一致性:指 数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对于银行转账事务,不管事务成功还是失败,应该保证事务结束后两个转账账户的存款总额是与转账前一致的。
隔离性:指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。(表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。)
持久性:指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
JavaBean中使用JDBC方式进行事务处理
1 public int delete(int sID) { 2 dbc = new DataBaseConnection(); 3 Connection con = dbc.getConnection(); 4 try { 5 con.setAutoCommit(false);// 更改JDBC事务的默认提交方式 6 dbc.executeUpdate("delete from xiao where ID=" + sID); 7 dbc.executeUpdate("delete from xiao_content where ID=" + sID); 8 dbc.executeUpdate("delete from xiao_affix where bylawid=" + sID); 9 con.commit();//提交JDBC事务 10 con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式 11 dbc.close(); 12 return 1; 13 } catch (Exception exc) { 14 con.rollBack();//回滚JDBC事务 15 exc.printStackTrace(); 16 dbc.close(); 17 return -1; 18 } 19 }
在数据库操作中,一项事务是指由一条或多条对数据库写操作的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作失败没有完成,就必须回滚撤消整个事务。
例如在银行的转帐事务中,假定张三从自己的帐号上把1000元转到李四的帐号上,相关的sql语句如下:
update account set monery=monery-1000 where name=’zhangsan’
update account set monery=monery+1000 where name=’lisi’
这两条语句必须作为一个完整的事务来处理。只有当两条都成功执行了,才能提交这个事务。如果有一条失败,整个事务必须撤消回滚。
四、SQL 标准定义了四种事务隔离级别,MySQL 全都支持。这四种隔离级别分别是:
(事务的隔离级别是指若干个并发的事务之间的隔离程度)
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
②读未提交(READ UNCOMMITTED):该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读。
③读提交 (READ COMMITTED):该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读。
④可重复读 (REPEATABLE READ):该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。
⑤串行化 (SERIALIZABLE):所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读和幻读。但是这将严重影响程序的性能。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
读提交(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable reads) | 不可能 | 不可能 | 可能 |
串行化(Serializable) | 不可能 | 不可能 | 不可能 |
以下几个概念是事务隔离级别要实际解决的问题:脏读,不可重复读,幻读。
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的就是脏数据。
2、不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
3、幻读:事务A对数据库的数据进行批量操作。事务B完成记录的添加,这时新加的记录可能就没有进行事务A的批量操作。
五、事务传播行为
spring事务的传播机制说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。事务传播机制实际上是使用简单的ThreadLocal实现的,所以,如果调用的方法是在新线程调用的,事务传播实际上是会失效的。
@Transactional 注解的 propagation 属性,用于定义事务传播行为 @Transactional( propagation = Propagation.REQUIRED)
Propagation.REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
Propagation.REQUIRES_NEW:创建一个新的食物,如果当前存在事务,则把当前事务挂起。
Propagation.SUPPORTS:如果当前存在事务 ,则加入该事务;如果当前没有事务,则以非事务方式继续运行。
Propagation.NOT_SUPPORTS:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则按REQUIRED属性执行。
Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。
Propagation.MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
@Transactional(isolation = Isolation.READ_COMMITTED)注解的 isolation 属性,用于定义事务隔离级别。
六、分布式事务
(1)JTA(Java Transaction API)
在应用系统数据量越来越大时,系统数据就需要分布在不同的数据库中,当业务需求在多个数据库中做原子性操作时就可以选择JTA (Java Transaction API),JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。
(2)JTA原理
不同的数据库有不同的数据库供应商,JTA就是将这个不同的数据库管理起来,统一创建一个原子事务,全部成功即成功,一个不成功就回滚所有的操作(JTA还是较重量级)
(3)实例
Spring有很多的JTA框架,这里使用的是atomikos框架。
(4)分布式消息最终一致性事务实现原理
当应用收到请求,应用会先将用户请求的数据保存到分布式消息中间件中,做一个保存操作。保存成功后就给用户返回提交成功信息。接着分布式消息中间件将请求在发送到不同的处理机器上,处理机器收到消息在进行业务处理。比如A给B转账,A先提交转账信息(已经扣款),然后消息被发送的分布式消息中间件上,消息中间件在发送到处理机器上面做处理,转账成功后则在给用户发送转账成功信息,不成功则把款退回去。
七、事务的属性可同通过注解方式或配置文件配置:
@Transactional只能被应用到public方法上,对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
默认情况下,一个有事务方法, 遇到RuntimeException 时会回滚 . 遇到 受检查的异常 是不会回滚 的. 要想所有异常都回滚,要加上 @Transactional( rollbackFor={IOException.class,其它异常})
1 @Transactional( 2 readOnly = false, //读写事务 3 timeout = -1 , //事务的超时时间,-1为无限制 4 noRollbackFor = ArithmeticException.class, //遇到指定的异常不回滚 5 isolation = Isolation.DEFAULT, //事务的隔离级别,此处使用后端数据库的默认隔离级别 6 propagation = Propagation.REQUIRED //事务的传播行为 7 )
2、配置文件( aop拦截器方式):
1 <tx:advice id="advice" transaction-manager="txManager"> 2 <tx:attributes> 3 <!-- tx:method的属性: 4 * name 是必须的,表示与事务属性关联的方法名(业务方法名),对切入点进行细化。通配符 5 (*)可以用来指定一批关联到相同的事务属性的方法。 6 如:'get*'、'handle*'、'on*Event'等等. 7 * propagation:不是必须的,默认值是REQUIRED表示事务传播行为, 8 包括REQUIRED,SUPPORTS,MANDATORY,REQUIRES_NEW,NOT_SUPPORTED,NEVER,NESTED 9 * isolation:不是必须的 默认值DEFAULT ,表示事务隔离级别(数据库的隔离级别) 10 * timeout:不是必须的 默认值-1(永不超时),表示事务超时的时间(以秒为单位) 11 * read-only:不是必须的 默认值false不是只读的表示事务是否只读? 12 * rollback-for: 不是必须的表示将被触发进行回滚的 Exception(s);以逗号分开。 13 如:'com.foo.MyBusinessException,ServletException' 14 * no-rollback-for:不是必须的表示不被触发进行回滚的 Exception(s),以逗号分开。 15 如:'com.foo.MyBusinessException,ServletException' 16 任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚 17 --> 18 <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> 19 <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> 20 <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" rollback-for="Exception"/> 21 <!-- 其他的方法之只读的 --> 22 <tx:method name="*" read-only="true"/> 23 </tx:attributes> 24 </tx:advice>
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29765.html