java 数据库 事务

数据库系统提供了四种事务隔离级别供用户选择:

A.Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新。

B.Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。

C.Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。

D.Read Uncommitted(读未提交数据):一个事务在执行过程中可以拷打其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以有优先考虑把数据库系统的隔离级别设为Read Commited,它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

当数据库系统采用read Commited隔离级别时,会导致不可重复读喝第二类丢失更新的并发问题,可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁可以分为以下几类:

A.悲观锁:指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题,但是它会影响并发性能,因此应该谨慎地使用。

B.乐观锁:乐观锁假定当前事务操作数据资源时,不回有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作。应用程序采用版本控制手段来避免可能出现的并发问题。

1.注解级别的实例

这里使用spring命名空间,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    default-autowire="byName"  default-lazy-init="true">

 <context:property-placeholder location="classpath:jdbc.properties" />


 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
  <property name="initialSize" value="${jdbc.initialSize}" />
  <property name="maxActive" value="${jdbc.maxActive}" />
  <property name="maxIdle" value="${jdbc.maxIdle}" />
  <property name="minIdle" value="${jdbc.minIdle}" />
  <property name="maxWait" value="${jdbc.maxWait}" />
 </bean>

 <!-- 设定transactionManager -->
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
 </bean>

<!--启动spring注解功能-->

 <tx:annotation-driven transaction-manager="transactionManager" />

 
</beans>

说明:

1.如果事务管理器的id是transactionManager,这里可以不对transaction-manager进行配置,即<tx:annotation-driven />就可以。

2.这个配置是告诉spring在类(接口)层面或者方法层面上检查应用程序上下文中的所有标准了@Transactional的bean,spring将自动把事务通知的内容通知给它。

3.这个通知的事务参数将由@Transactional注释的参数来定义。

4.如果注释的是接口,则该接口的所有实现类都将被事务化。

二.使用@Transactional标注bean

package com.netqin.bbs.initUserData;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.netqin.bbs.initUserData.service.InitUserDataService;
import com.netqin.bbs.utils.Constant;
import com.netqin.bbs.utils.ReadFileUtil;

@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)//设置默认的事务管理策略,即没有标注@Transactional的方法的事务处理方式,意思为不要求方法必须在一个事务中运行
public class InitUserData {
 /**                                                         
 * 描述 :使用方法上声明的事务管理策略,这里的意思为需要在一个事务中运行. <br>
 *<p>                                                 
                                                                                                                                                                                                                                                                                                
 */
 @Transactional(propagation=Propagation.REQUIRED,readOnly=false)
 public void method1(){

  ……………………

  ……………………   
 
 }

2.编程级别事务

 <!-- 编程级事务 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager">
            <ref bean="txManager" />
        </property>
    </bean>
   
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="gameDataSource" />
    </bean>
   
     <bean id="test2" class="BatchTest.test2.MainTest">
     <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

java文件中

private TransactionTemplate transactionTemplate;
 
 public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
  this.transactionTemplate = transactionTemplate;
 }

执行方法:  
  transactionTemplate.execute(new TransactionCallback() {
   @Override
   public Object doInTransaction(TransactionStatus status) {
    try{
     ....执行语句

    }catch(Exception e){
     e.printStackTrace();
     status.setRollbackOnly();
    }
    return null;
   }
  });

猜你喜欢

转载自lf6627926.iteye.com/blog/1696607
今日推荐