Java的事务处理

今天面试有关Java事务,当时有点懵,只是记得commit,rollback什么的,在具体就不知道到底什么怎么回事了。

所以回来赶紧查查网上的有关事务的文章。

事务(transaction):数据库保证交易可靠的机制,JDBC支持数据库中的事务概念,并且在JDBC中,事务是默认自动提交的。

简单点就是:Java的事务处理,如果对数据库进行多次的操作,每一次的执行或者步骤都是有一个事务,如果数据库操作在某一步没有执行或者出现异常导致事务失败,这样有的事务被执行有的没有被执行,从而就有了事务回滚,取消先前的操作了....

JDBC中和事务相关的API:

 JDBC标准事务编程模式:

try{
	// 1.定义用于在事务中执行的SQL语句
	String sql1 = "update account set amount = amount - " + amount + " where id = '" + from + "'";
	String sql2 = "update account set amount = amount + " + amount + " where id = '" + to + "'";
	autoCommit = con.getAutoCommit(); // 2.获得自动提交状态
	con.setAutoCommit(false); // 3.关闭自动提交
	stmt.executeUpdate(sql1); // 4.执行SQL语句
	stmt.executeUpdate(sql2);
	con.commit(); // 5.提交
	con.setAutoCommit(autoCommit); // 6.将自动提交功能恢复到原来的状态
	//其他语句;
}catch(SQLException e){
    conn.rollback();//异常时回滚
}
在数据库操作中,一项事务是指由一条或多条对数据库更新的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作没有完成,就必须撤消整个事务。 

例如在银行的转帐事务中,假定张三从自己的帐号上把1000元转到李四的帐号上,相关的sql语句如下: 
update account set monery=monery-1000 where name='zhangsan' 
update account set monery=monery+1000 where name='lisi' 
这个两条语句必须作为一个完成的事务来处理。只有当两条都成功执行了,才能提交这个事务。如果有一句失败,整个事务必须撤消。


Spring的事务处理(aop 事务处理):声明式事务处理

传统编程事务处理非常繁琐:

try{
   conn=打开连接
   conn.setAutoCommit(false);
   //数据库操作1
   //数据库操作2
   //数据库操作3
   conn.commit();
}catch(e){
   conn.rollback();
}finally{
   conn.close()
}

声明式事务处理, 底层是利用AOP实现的, 只需要简单配置即可使用.



1.基于注解配置事务管理器:

<!-- spring-mybatis.xml -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"
        ref="dataSource"/>
</bean>
<!-- 设置 注解驱动的事务管理  -->
<tx:annotation-driven 
    transaction-manager="txManager"/>

在业务方法上使用 事务注解(@Transactional)即可:
@Transactional
public int deleteNotes(String... noteIds) 
        throws NoteNotFoundException {
.....
}

2.使用XML AOP事务管理 
<tx:advice/>标签,该标签会创建一个事务处理通知:
tx:advice id="txAdvice" transaction-manager="transactionManager">  
    <tx:attributes>  
        <tx:method name="bulk*" propagation="REQUIRED" isolation="DEFAULT" />  
        <tx:method name="load*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>  
    </tx:attributes>  
</tx:advice>  
<aop:config>  
        <aop:advisor pointcut="execution(* *..*Service*.*(..))" advice-ref="txAdvice" />  
</aop:config>  
  
或  
<aop:config>  
    <aop:pointcut id="allServiceMethods"  
                  expression="execution(* com.apress.prospring2.ch16.services.*.*(..))"/>  
    <aop:advisor advice-ref="defaultTransactionAdvice"  
                 pointcut-ref="allServiceMethods"/>  
</aop:config>  
<tx:advice id="defaultTransactionAdvice" transaction-manager="transactionManager">  
    <tx:attributes>  
</tx:advice>  
        <tx:method  
                name="*"  
                isolation="DEFAULT"  
                propagation="REQUIRED"  
                no-rollback-for="java.lang.RuntimeException"  
                timeout="100"/>  
        <tx:method  
                name="get*"  
                read-only="true"/>  
    </tx:attributes>  

<tx:advice>标签简介 :
id是该advice bean的标识,而transaction-manager则必须引用一个PlatformTransactionManager bean。 
还可以通过<tx:attributes>标签定制<tx:advice>标签所创建的通知的行为。 

<tx:method/>标签的属性:
 
name:方法名的匹配模式,通知根据该模式寻找匹配的方法。 
propagation:设定事务定义所用的传播级别。 
isolation:设置事务的隔离级别。 
timeout:指定事务的超时(秒)。 
read-only:该属性为true指示事务是只读的 
no-rollback-for:以逗号分隔的异常类的列表,目标方法可以跑出这些异常而不会导致通知执行回滚 
rollback-for:以逗号分隔的异常类的列表,当目标方法跑出这些异常时会导致通知执行回滚。默认情况下,该列表为空,因此不在no-rollback-for列表中的任何运行时异常都会导致回滚。 



<tx:method>中isolation(隔离)和propagation(传播)参数的含义: 
getIsolationLevel:他对其他事务所看到的数据变化进行控制。


3.只读属性

对于单纯读取数据库操作, 可以设置readOnly=true, 可以提高数据的效率.

@Transactional(readOnly=true)
public List<Map<String, Object>> listNotesInTrashBin(
        String userId) throws UserNotFoundException {
4.事务的传播:

业务过程重构时候需要业务方法调用业务方法, 这样就需要一个业务方法的事务传播到另外一个业务方法中, 整合为一个事务.

事务传播的属性:

@Transactional(propagation=Propagation.REQUIRED)
@Transactional(propagation=Propagation.MANDATORY)
@Transactional(propagation=Propagation.NEVER)
@Transactional(propagation=Propagation.NESTED)
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@Transactional(propagation=Propagation.SUPPORTS)
@Transactional(propagation=Propagation.REQUIRES_NEW)

5.事务隔离级别: 
隔离级别 说明 
ISOLATION_DEFAULT 默认级别(对大多数数据库来说就是ISOLATION_READ_COMMITTED) 
ISOLATION_READ_UNCOMMITTED 最低的隔离级别。事实上我们不应该隔离级别,因为在事务完成前,其他事务可以看到该事务所修改的数据。而在其他事务提交前,该事务也可以看到其他事务所做的修改。 
ISOLATION_READ_COMMITTED 大多数数据库的默认级别。在事务完成前,其他事务无法看到该事务所修改的数据。遗憾的是,在该事务提交后,你就可以查看其他事务插入活更新的数据。这意味着在事务的不同点上,如果其他事务修改数据,你会看到不同的数据。 
ISOLATION_REPEATABLE_READ 该隔离级别确保如果在事务中查询了某个数据集,你至少还能再次查询到相同的数据集,即使其他事务修改了所查询的数据。然而如果其他事务插入了新数据,你就可以查询到该新插入的数据。 
ISOLATION_SERIALIZABLE 代价最大、可靠性最高的隔离级别,所有的事务都是俺顺序一个接一个的执行。 
getPropagationBehavior:指定了当代码请求一个新的事务时Spring所做的事情。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值