事务管理

事务管理

MYSQL中的事务
*开启事务:start transaction
提交:commit;
回滚:rollback;

JDBC事务
在jdbc中处理事务,都是通过Connection完成的!
在同一事务中所有的操作都在使用同一个Connection对象

Connection中的三个方法与事务有关:
setAutoCommit(boolean):设置是否为自动事务提交。如果为true,表示每一条单独的SQL都是一个单独的事务。
如果设置false,就相当于开启了事务;con.setAutoCommit(false)表示开启事务!!!)
commit():提交结束书屋
rollback():回滚结束事务

jdbc处理事务的代码格式:
try{
con.setAutoCommit(false);
...
...
con.commit();
}catch(){
con.rollback();
}

事务的隔离级别
1.事务的并发读问题
*脏读:读取到另一个事务未提交数据
*不可重复读:两次读取不一致
*幻读(虚读):督导另一事务已提交数据
2.并发事务问题
*脏读:读到另一个事务的未提交更新数据,即读取到了脏数据
*不可重复读:对同一记录的两次读取不一致,因为另一事务对该记录做了修改
*幻读:对同一张表的两次查询不一致,因为另一事务插入了一条记录
3.四大隔离级别
用来防止并发问题
*serializable(串行化)
不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的
性能最差
*repeatable read(可重复读)(mysql)
防止脏读和不可重复读,不能处理幻读问题
性能比serializable好
*read committed(读已提交数据)(oracle)
防止脏读,没有处理不可重复读,也没有处理幻读
性能比repeatable read好
*read uncommitted(读未提交数据)
可能出现并发问题
性能最好

查询数据库的隔离级别:
SELECT @@tx_isolation;
设置当前连接的隔离级别:settransaction isolationlevel [4选1]

JDBC设置隔离级别:
con.setTransactionIsolation(int level)
可选参数:
Connection.TRANSACTION_READ_UNCOMMITTED;
Connection.TRANSACTION_READ_COMMITTED;
Connection.TRANSACTION_REPEATABLE_READ;
Connection.TRANSACTION_SERIALIZABLE;

package cn.itcast.demo;

import java.sql.Connection;
import java.sql.PreparedStatement;


public class AccountDao { 
    
    public void updateBalance(Connection con,String name,double balance){
        try{
            
            String sql="UPDATE account SET balance=balance+? WHERE aname=?"; 
            PreparedStatement pstmt=con.prepareStatement(sql);
            
            pstmt.setDouble(1, balance);
            pstmt.setString(2, name);
            
            pstmt.executeUpdate();
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}
package cn.itcast.demo;

import java.sql.Connection;
import java.sql.SQLException;

import org.junit.Test;

import cn.itcast.jdbc.JdbcUtils;

/**
 * 所有对Connection的操作都在service层进行处理!
 * 将要处理这个问题,将所有对Connection的操作隐藏起来,需要使用自定义的小工具
 * @author Administrator
 *
 */
public class Demo1 {
    /**
     * 转账方法
     * @param from
     * @param to
     * @param money
     */
    public void zhuanZhang(String from,String to,double money){
        /**
         * 注意必须使用同一个Connection对象
         */
        Connection con=null;
        try{
            con=JdbcUtils.getConnection();
            con.setAutoCommit(false);
            
            AccountDao dao=new AccountDao();
            dao.updateBalance(con,from, -money);
            
            if(true){
                throw new RuntimeException("不好意思");
            }
            
            dao.updateBalance(con,to, money);
            
                    
            con.commit();
        }catch(Exception e){
            try {
                con.rollback();
                con.close();
            } catch (SQLException e1) {
            }
            throw new RuntimeException(e);
        }
    }
    
    @Test
    public void fun1(){
        zhuanZhang("zs","lisi",100);  
        
    }

}
View Code
原文地址:https://www.cnblogs.com/aigeileshei/p/5714056.html