jdbc的事务操作主要由java.sql.Connection类处理。 有三个方法:
setAutoCommit(boolean) 是否自动提交rollback() 回滚commit() 提交传统的jdbc的操作: (1)驱动注册 (2)获取链接Connection (3)statement预编译sql (4)执行sql (5)处理结果集 (6)处理异常回滚并释放资源 (7)释放结果集 (8)释放statement (9)事务提交 (10)释放链接 优缺点: API简单,可以实现基本的事务功能; 局限于与一个数据库链接,不能涉及到多个数据库,
不是很了解,等待后续的更新
容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。有EJB和spring,主要了解spring事务。 spring并不直接管理事务,而是提供多个事务管理器,将事务的职责委托给相应的平台。 spring框架事务涉及到三个核心接口 PlatformTransactionManager,主要用于管理事务。 TransactionManagerDefinition:事务的定义 TransactionStatus:表示一个事务
//事务的主要方法及参数 TransactionStatus getTransaction(TransactionManagerDefinition); commit(TransactionStatus); rollback(TransactionStatus).传播行为,隔离规则,回滚规则,事务超时,是否只读 7种传播行为: PROPAGATION_REQUIRED:当前没有事务,则创建一个事务,如果已经存在一个事务,则加入其中。 PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,则以非事务的方式执行。 PROPAGATION_MANDATORY:支持当前事务,如果没有事务,则抛出异常 PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,则挂起 PROPAGATION_NOT_SUPPORTS:以非事务方式执行,如果存在事务,将当前事务挂起 PROPAGATION_NEVER:以事务执行,如果当前存在事务,则抛出异常 PROPAGATION_NESTED:如果存在事务,则创建一个事务,并嵌套进去,如果不存在事务,则创建事务执行。 spring默认required.常用1,4级别
隔离级别是为应对多个事务,多个事务的并发可能会出现以下问题:
脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。注:
不可重复读和幻读都是重复查询时出现问题,但是不一样的是,不可重复读更注重的是查询的数据数量不变,但是数据变了;幻读则是第二次查询发现查询出的行数发现了变化,数据行数变化,原数据的数据没变。spring的隔离级别选择
ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别。使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
ISOLATION_READ_UNCOMMITTED:读取为提交的内容。最低隔离级别,允许其他事务读取其他未提交事务的数据。可能造成脏读,不可重复读,幻读。
ISOLATION_READ_COMMITTED:读取提交的内容。保证一个事务只能在其他事务提交之后才能读取,可以避免脏读,但是不能避免不可重复读和幻读。
ISOLATION_ISOLATION_REPEATABLE_READ:可重读。这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。可避免脏读和不可重复读,但是可能出现幻读。
ISOLATION_SERIALIZABLE:可串行化。这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。避免所有的问题
两种方式: 1.编程式事务:通过编写代码实现事务管理,包括事务的开始、提交、回滚。 2.声明式事务:通过aop技术来实现事务管理,将事务管理织入到业务目标中。主要使用。
编程式事务可使用spring提供的事务模板类 transactionTemplate。执行execute()方法,在参数的内部实现中编写逻辑代码。 也可以自定义TransactionDefinition,然后通过PlatformTransactionManager获取TransactionStatus,使用PlatformTransactionManager来实现提交和回滚。 不推荐,代码耦合性太高。声明式事务主要xml配置和注解配置 基于xml: spring2.0以后,提供了tx命名空间来配置事务。
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- tx:method的属性: * name 是必须的,表示与事务属性关联的方法名(业务方法名),对切入点进行细化。通配符 (*)可以用来指定一批关联到相同的事务属性的方法。 如:'get*'、'handle*'、'on*Event'等等. * propagation:不是必须的,默认值是REQUIRED表示事务传播行为, 包括REQUIRED,SUPPORTS,MANDATORY,REQUIRES_NEW,NOT_SUPPORTED,NEVER,NESTED * isolation:不是必须的 默认值DEFAULT ,表示事务隔离级别(数据库的隔离级别) * timeout:不是必须的 默认值-1(永不超时),表示事务超时的时间(以秒为单位) * read-only:不是必须的 默认值false不是只读的表示事务是否只读? * rollback-for: 不是必须的表示将被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException' * no-rollback-for:不是必须的表示不被触发进行回滚的 Exception(s),以逗号分开。 如:'com.foo.MyBusinessException,ServletException' 任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚 --> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" rollback-for="Exception"/> <!-- 其他的方法之只读的 --> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="point"/> <aop:advisor advice-ref="txAdvice" proint-ref="point"/> </aop:config>基于注解: 需要在xml配置文件中,开启注解处理器< context:annotation-config/>,同时注册事务管理驱动器< tx:annotation-driver transaction-manager=""/>
@Transactional( readOnly = false, //读写事务 timeout = -1 , //事务的超时时间,-1为无限制 noRollbackFor = ArithmeticException.class, //遇到指定的异常不回滚 isolation = Isolation.DEFAULT, //事务的隔离级别,此处使用后端数据库的默认隔离级别 propagation = Propagation.REQUIRED //事务的传播行为 )参考原文: mysql的隔离级别: Java事务 编程式事务: 事务百科: