JavaWeb——Day11_1

本文介绍数据库事务的概念及其四大特性:原子性、一致性、隔离性和持久性,并探讨了四种不同的事务隔离级别及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*1.事务概念_四大特性


create table account (
id int primary key auto_increment,
name varchar(20),
money double
);
insert into account values(null,'a',1000),(null,'b',1000);





一、事务
    事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成.
      
    事务的管理:默认情况下,数据库会自动管理事务,管理的方式是一条语句就独占一个事务.
                如果需要自己控制事务也可以通过如下命令开启/提交/回滚事务
                start transaction;
                commit;
                rollback;


在jdbc中管理事务:

package com.itheima.transaction;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;

import com.itheima.util.JDBCUtils;

public class JDBCTranDemo {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		Savepoint sp = null;
		try{
			conn = JDBCUtils.getConn();
			conn.setAutoCommit(false);
			
			ps = conn.prepareStatement("update account set money=money-100 where name = ?");
			ps.setString(1, "a");
			ps.executeUpdate();

			ps = conn.prepareStatement("update account set money=money+100 where name=?");
			ps.setString(1, "b");
			ps.executeUpdate();
			
			//设置回滚点
			sp = conn.setSavepoint();
			
			ps = conn.prepareStatement("update account set money=money-100 where name = ?");
			ps.setString(1, "a");
			ps.executeUpdate();
			
			String str = null;
			str.toUpperCase();
			
			ps = conn.prepareStatement("update account set money=money+100 where name=?");
			ps.setString(1, "b");
			ps.executeUpdate();
			
			conn.commit();
		}catch (Exception e) {
			try {
				if(sp == null){//如果回滚点为null说明没有执行到设置回滚点代码时就抛了异常,应该所有语句进行回滚
					conn.rollback();	
				}else{//说明sp不为null,可以会滚到回滚点,接着执行其他操作,但是要注意,如果希望之前的语句起作用,仍然需要做提交操作
					conn.rollback(sp);
					conn.commit();
				}
				
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			JDBCUtils.close(rs, ps, conn);
		}
	}
}


  JDBC中管理事务:
                    conn.setAutoCommit(false);
                    conn.commit();
                    conn.rollback();
                    SavePoint sp = conn.setSavePoint();
                    conn.rollback(sp);


               
    事务的四大特性:一个事务具有的最基本的特性,一个设计良好的数据库可以帮我们保证事务具有这四大特性(ACID)
        原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 
        一致性:如果事务执行之前数据库是一个完整性的状态,那么事务结束后,无论事务是否执行成功,数据库仍然是一个完整性状态.
            数据库的完整性状态:当一个数据库中的所有的数据都符合数据库中所定义的所有的约束,此时可以称数据库是一个完整性状态.
        隔离性:事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
        持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。




 隔离性:
        将数据库设计成单线程的数据库,可以防止所有的线程安全问题,自然就保证了隔离性.但是如果数据库设计成这样,那么效率就会极其低下.


*2.事务四大隔离级别

如果是两个线程并发修改,一定会互相捣乱,这时必须利用锁机制防止多个线程的并发修改
        如果两个线程并发查询,没有线程安全问题
       
        如果两个线程一个修改,一个查询......

第一个问题:



第二个问题:





虚读:




 虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致 --- 表级别的问题
            a: 1000
            b: 1000
            d: 银行业务人员
            
            -----------
            d:
                start transaction;
                select sum(money) from account; --- 2000 元
                select count(name) from account; --- 2 个
                
                ------
                c:
                    start transaction;
                        insert into account values(c,4000);
                     commit;
                ------
               
                select sum(money)/count(name) from account; --- 平均:2000元/个
                commit;
            ------------



四大隔离级别:
                Read uncommitted -- 不防止任何隔离性问题,具有脏读/不可重复度/虚读(幻读)问题
                Read committed -- 可以防止脏读问题,但是不能防止不可重复度/虚读(幻读)问题
                Repeatable read -- 可以防止脏读/不可重复读问题,但是不能防止虚读(幻读)问题
                Serializable -- 数据库被设计为单线程数据库,可以防止上述所有问题

 从安全性上考虑: Serializable>Repeatable read>read committed>read uncommitted
 从效率上考虑: read uncommitted>read committed>Repeatable read>Serializable

真正使用数据的时候,根据自己使用数据库的需求,综合分析对安全性和对效率的要求,选择一个隔离级别使数据库运行在这个隔离级别上.
                mysql 默认下就是Repeatable read隔离级别
                oracle 默认下就是read committed个隔离级别

查询当前数据库的隔离级别:select @@tx_isolation;
                设置隔离级别:set [global/session] transaction isolation level xxxx;其中如果不写默认是session指的是修改当前客户端和数据库交互时的隔离级别,而如果使用golbal,则修改的是数据库的默认隔离级别





多练习这个锁机制!!!在dos界面!



*3.更新丢失_乐观锁_悲观锁

丢失更新!






更新丢失问题:
            两个线程基于同一个查询结果进行修改,后修改的人会将先修改人的修改覆盖掉.
            
            悲观锁:悲观锁悲观的认为每一次操作都会造成更新丢失问题,在每次查询时就加上排他锁
                  
            乐观锁:乐观锁会乐观的认为每次查询都不会造成更新丢失.利用一个版本字段进行控制
                
             
                  查询非常多,修改非常少,使用乐观锁
                  修改非常多,查询非常少,使用悲观锁







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值