数据库的事务及实现CRUD功能 - Go语言中文社区

数据库的事务及实现CRUD功能


一、概念

一组逻辑操作单元(一个或多个DML操作),使数据从一种状态变换到另一种状态。

二、事务的属性(ACID)

1.原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2.一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另一个一致性状态。
3.隔离性(Isolation)
事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

2.1 数据库的并发问题

数据操作过程中可能出现的问题:(针对隔离性)

  • 脏读
    对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的。
  • 不可重复读
    对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。
  • 幻读
    对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行。之后, 如果 T1 再次读取同一个表, 就会多出几行。

2.2 四种隔离级别

在这里插入图片描述

  • mysql默认REPEATABLE READ

二、事务处理原则

保证所事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态

三、说明

1.数据一旦提交,就不可回滚
2.哪些操作会导致数据的自动提交?

  • DDL操作一旦执行,都会自动提交。
    set autocommit = false 对DDL操作失效
  • DML默认情况下,一旦执行,就会自动提交。
    我们可以通过set autocommit = false的方式取消DML操作的自动提交。
  • 默认在关闭连接时,会自动的提交数据

四、代码体现

1.获取数据库的连接

Connection conn = JDBCUtils.getConnection();== //方式1:手动获取连接 方式2:数据库连接池==

conn.setAutoCommit(false); //体现事务

2.如下的多个DML操作,作为一个事务出现:

操作1:需要使用通用的增删改查操作
//通用的增删改查操作如何实现?//方式1:手动使用PreparedStatement实现;//方式2:使用dbutils.jar中QueryRunner类
操作2:需要使用通用的增删改查操作

操作3:需要使用通用的增删改查操作

conn.commit();

3.如果出现异常

conn.rollback();

4.关闭资源

JDBCUtils.closeResource(…,…,…); //方式1:手动关闭资源 方式2:DbUtils类的关闭方法

     @Test
	public void testUpdateWithTx() {
		Connection conn = null;
		try {
			conn = JDBCUtils.getConnection();
			System.out.println(conn.getAutoCommit());//true
			//1.取消数据的自动提交
			conn.setAutoCommit(false);
			
			String sql1 = "update user_table set balance = balance - 100 where user = ?";
			update(conn,sql1, "AA");
			
			//模拟网络异常
			System.out.println(10 / 0);
			
			String sql2 = "update user_table set balance = balance + 100 where user = ?";
			update(conn,sql2, "BB");
			
			System.out.println("转账成功");
			
			//2.提交数据
			conn.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			//3.回滚数据
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}finally{
			//修改其为自动提交数据
			//主要针对于使用数据库连接池的使用
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
			JDBCUtils.closeResource(conn, null);
		}
		
	}
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Kris_Zeng_/article/details/113482237
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢