【事务概述】

       1.什么是事务?

              逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全部失败。

       2.mysql事务

               默认的事务:一条sql语句就是一个事务,默认就开启事务并提交事务。

               手动事务:(1)  显示的开启一个事务 -- start transaction

                             (2)  事务提交 -- commit  代表从开启事务到提交事务 中间所有的sql语句都认为有效,真正的更新数据库。

                             (3)  事务的回滚 -- rollback  从开启事务到回滚事务 中间所有sql操作都认为无效,数据库没更新。

【JDBC事务操作】  

             (1).  默认是自动事务   执行sql语句:executeUpdate(),每执行一次executeUpdate()方法代表事务自动提交。 

             (2).  手动事务    开启事务:con.setAutoCommit(false);   提交事务:con.commit();  回滚事务:con.rollback();

             注意:控制事务的connextion必须是同一个。         

 

【DBUtils事务操作】  

             (1) 有参构造:QueryRunner  runner = new QueryRunner(DataSource  dataSource)   将数据源(连接池)作为参数传入QueryRunner,QueryRunner会从连接池中获得一个数据库连接资源操作数据库,所以可以直接使用无Connection参数的update方法即可操作数据库。

             (2) 无参构造:QueryRunner  runner = new QueryRunner()   没有将数据源作为参数传入QueryRunner,操作数据库的时候,要使用有Connection参数的方法。

 

 【ThreadLocal工具类】-- 在一个线程中共享数据

             ThreadLocal工具类底层就是一个Map,key存放的当前线程,value存放共享的数据。

             ThreadLocal操作: set(value)     get()     remove()

c3p0-config.xml 数据库配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///mybase1</property>
		<property name="user">root</property>
		<property name="password">123</property>
		<property name="initialPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>

	<named-config name="namedConfig">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///mybase1</property>
		<property name="user">root</property>
		<property name="password">123</property>
	</named-config>

</c3p0-config>

【ThreadLocal 在当前线程中存储Connection】 

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Utils {
	// 使用默认配置信息 -- 自动读取c3p0-config.xml中的配置信息
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	// 创建ThreadLocal -- 用于在当前线程中共享数据
	private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
	
	// 静态方法获得连接池
	public static DataSource getDataSource() {
		return dataSource;
	}
	
	// 静态方法获得连接池
	public static Connection getConnection() throws SQLException {
			return dataSource.getConnection();
	}
	
	// 开启事务
	public static void startTransaction() throws SQLException {
		Connection con = getCurrentConnection();
		con.setAutoCommit(false);
	}
	
	// 回滚事务
	public static void rollback() throws SQLException {
		getCurrentConnection().rollback();
	}
	
	// 提交事务
	public static void commit() throws SQLException {
		Connection con = getCurrentConnection();
		con.commit();
		// 将Connection从ThreadLocal中删除
		tl.remove();
		con.close();
	}
	
	// 获得当前线程绑定的Connection
	public static Connection getCurrentConnection() throws SQLException {
		// 从ThreadLocal寻找,当前线程是否有对应的Connection
		Connection con = tl.get();
		if(con == null) {
			// 获得新的Connecton资源
			con = getConnection();
			// 将Connection资源绑定到ThreadLocal
			tl.set(con);
		}
		return con;
	}

}

事务的特性

(1)原子性(Automicity) 原子性是指事务一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

(2)一致性(Consistency) 事务前后数据的完整性必须保持一致。

(3)隔离性(Isolation) 多个用户并发访问数据库时,一个用户的事物不能被其他用户的事物所干扰,多个并发事物之间数据要隔离。

(4)持久性(Durability)一个事务一旦被提交,它对数据库中数据的改变是持久性的,接下来即使数据库发生故障也不应该对其有任何影响。

并发访问问题】--- 由隔离性引起

(1)脏读:B事务读到了A事务未提交的数据。--- 要求B事务要读取A事务提交的数据。

(2)不可重复读:一个事务中  两次读取到数据内容不一致 --- 要求的是一个事务中多次读取到的数据是一致的。

(3)虚读/幻读: 一个事务中  两次读取的数据的数量不一致 --- 要求在一个事务多次的数据的数量是一致的。

解决并发问题】--- 设置隔离级别

(1)read uncommitted: 读取尚未提交的数据:哪个问题都不能解决。

(2)read committed: 读取已经提交的数据:可以解决脏读。--- oracle 默认的。

(3)repeatable read : 重读读取:可以解决脏读 和 不可重复读。--- mysql 默认的。

(4)serializable:串行化:可以解决脏读,不可重复读 和 虚读。--- 相当于锁表。

查看mysql数据库默认的隔离级别:select @@tx_isolation

设置事务的隔离级别:set session  transaction isolation  level  事务隔离级别

【总结】

mysql的事务控制:
         开启事务:start  transaction
         提交事务:commit         回滚:rollback
JDBC 事务控制
         开启事务:con.setAutocommit(false)         提交事务:con.commit()         回滚:con.rollback()
DBUtils的事务控制  也是通过jdbc控制
ThreadLocal:实现的是通过线程绑定的方式传递参数
概念:
事务的特性:ACID
并发问题:脏读、不可重读、幻读
解决并发问题:设置隔离级别
read   uncommittedread   committedrepeatable  read(mysql默认)
serialazable
隔离级别的性能:
    read uncommitted>read committed>repeatable read>serialazable安全性:
    read uncommitted<read committed<repeatable read<serialazable