事务:
事务是指逻辑上的一组操作,组成这组操作的各个逻辑单元要么一起成功, 要么一起失败。
mysql的事务管理有两种:(在mysql数据库中直接操作[黑窗口]) 1.手动开启事务: a: start transaction;--开启事务 b: 执行多条sql语句 c: commit/rollback;--提交事务或者回滚事务 2.设置一个自动提交参数: 查看与commmit相关参数:show variables like "%commit%" 可以查看到一个名为autocommit的属性 设置autocommit属性值 set autocommit = 0;--将autocommit的值设置为off,默认是on开启状态。(0代表off,1代表on) 注意:mysql数据库事务默认是自动提交的; oralce数据库事务默认是不自动提交的。 jdbc的事务管理 java.sql.Connection API: void setAutoCommit(boolean flag):设置此连接的自动提交状态 void commit() :提交此连接的事务 void rollback() :回滚此连接的事务事务特性:
原子性:强调事务的不可分割性。
一致性:强调的是事务的执行前后,数据的完整性要保持一致。 隔离性:一个事务的执行不应该受到其他事务的干扰。 持久性:事务一旦结束(commit/rollback)数据就持久到了数据库中。 注意:如果不考虑事务的隔离性,引发一些安全性问题: 一类读问题: 脏读:一个事务读到另一个事务还没有提交的数据。 不可重复度:;一个事务读到了另一个事务已经提交的update的数据,导致在当前的事务中多次查询结果不一致。 虚度/欢度:一个事务读到了另一个事务已经提交的insert数据,导致在当前的事务中多次查询结果不一致。 一类写问题: 引发两类丢失更新。 解决引发的读问题: 设置事务的隔离级别: read uncommitted: 未提交读(脏读,不可重复读,虚度都可能发生) read committed: 已提交读(避免脏读,但是不可重复读和虚读有可能发生) repeatable read: 可重复度(避免脏读和不可重读读,但是虚读有可能发生) serializable: 串行化(避免脏读,不可重复读,虚读的发生)mysql设置事务的隔离级别:
查看连接的隔离级别:select @@tx_isolation;
设置连接(黑窗口)的隔离级别为:read uncommitted:
set session transaction isolation level read uncommitted;
设置连接(黑窗口)的隔离级别为:read committed:
set session transaction isolation level read committed;
设置连接(黑窗口)的隔离级别为:repeatable read:
set session transaction isolation level repeatable read;
设置连接(黑窗口)的隔离级别为:serializable:
set session transaction isolation level serializable;
jdbc设置事务的隔离级别:
Connection API:
void setTransactionIsoLation(int level):设置事务的隔离级别。
注意:不论是通过黑窗口或者jdbc连接数据库都是仅仅建立了一条Connection连接,设置事务隔离级别也是仅仅针对该Connection进行设置。
事务管理两种实现方法:
一: 将Connection一层层向下传递,DBUtils 进行事务管理使用的就是这种方法。 二: 在业务层获得connection将这个连接绑定到当前线程中,从当前线程中获取。hibernate底层事务管理使用的是这种方法。ThreadLocal 本地线程类
它里面维护的是map,map的key是当前线程,map的value是要绑定的东西,绑定的时候set(value),获取的时候get()获得value。示例代码:
import java.sql.Connection;import java.sql.SQLException;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class JdbcUtils { private static final ComboPooledDataSource DATASOURCE = new ComboPooledDataSource(); private static final ThreadLocalTL = new ThreadLocal (); public static DataSource getDataSource() { return DATASOURCE; } public static Connection getConn() throws SQLException { if (TL.get() == null) { TL.set(DATASOURCE.getConnection()); } return TL.get(); } public static void beginTranscation() throws SQLException { if (TL.get() == null) { TL.set(DATASOURCE.getConnection()); } TL.get().setAutoCommit(false); } public static void committranscation() throws SQLException { if (TL.get() == null) { TL.set(DATASOURCE.getConnection()); } TL.get().commit(); } public static void roolbackTranscation() throws SQLException { if (TL.get() == null) { TL.set(DATASOURCE.getConnection()); } TL.get().rollback(); }}