Java 中的事务详解以及使用

一、事务相关的概念介绍

什么是事务?

事务是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合;

事务的特性? (ACID特性)

  • 原子性(atomicity):事务是一个不可分割的工作单位,事务中的操作要么都修改,要么都不修改
  • 一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态
  • 隔离性(isolation):一个事务的执行不能被其他事务所影响
  • 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的

事务的隔离级别

  • Read uncommitted (读未提交)
    如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。这样就避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据
  • Read committed(读提交)
    读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变
  • Repeatable read(可重复读取)
    可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,即使第二个事务对数据进行修改,第一个事务两次读到的的数据是一样的。这样就发生了在一个事务内两次读到的数据是一样的,因此称为是可重复读。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。这样避免了不可重复读取和脏读,但是有时可能出现幻象读。(读取数据的事务)这可以通过“共享读锁”和“排他写锁”实现。
  • Serializable(序列化)
    提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读

事务运行的三种模式

  1. 自动提交事务:每条单独的语句都是一个事务,每个语句都隐含一个 commit;
  2. 显式事务:以 begin transaction 开始,以 commit 或者 rollback 结束;
  3. 隐性事务:在前一个事务完成时,新事务隐式启动,但每个事务仍以 commit 或者 rollback 显式结束;

Spring 中事务的传播属性

所谓spring事务的传播属性,就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。这些属性在TransactionDefinition中定义,具体常量的解释见下:
  • Propagation.REQUIRED(required):支持当前事务,如果当前有事务, 那么加入事务, 如果当前没有事务则新建一个(默认情况)
  • Propagation.NOT_SUPPORTED(not_supported) : 以非事务方式执行操作,如果当前存在事务就把当前事务挂起,执行完后恢复事务(忽略当前事务);
  • Propagation.SUPPORTS (supports) :如果当前有事务则加入,如果没有则不用事务。
  • Propagation.MANDATORY (mandatory):支持当前事务,如果当前没有事务,则抛出异常。(当前必须有事务)
  • PROPAGATION_NEVER (never) :以非事务方式执行,如果当前存在事务,则抛出异常。(当前必须不能有事务)
  • Propagation.REQUIRES_NEW (requires_new):支持当前事务,如果当前有事务,则挂起当前事务,然后新创建一个事务,如果当前没有事务,则自己创建一个事务。
  • Propagation.NESTED (nested 嵌套事务):如果当前存在事务,则嵌套在当前事务中。如果当前没有事务,则新建一个事务自己执行(和required一样)。嵌套的事务使用保存点作为回滚点,当内部事务回滚时不会影响外部事物的提交;但是外部回滚会把内部事务一起回滚回去。(这个和新建一个事务的区别)

二、手动提交事务

三、Spring 中的事务注解: @Transactional

四、代码实现

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java消息队列(Message Queue)是一种异步通信机制,用于在组件之间传递消息。它可以缓存和传递消息,从而实现解耦和异步处理。在Java,有很多消息队列的实现,比如ActiveMQ、RabbitMQ、Kafka等。 下面是Java消息队列的使用详解: 1. 创建消息队列 首先,需要创建一个消息队列。这可以通过调用相应消息队列的API来实现。例如,在ActiveMQ,可以通过如下代码创建一个队列: ``` ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = session.createQueue("myQueue"); ``` 2. 发送消息 要发送消息到队列,可以使用生产者(Producer)。生产者可以将消息发送到队列,如下所示: ``` MessageProducer producer = session.createProducer(queue); TextMessage message = session.createTextMessage("Hello World!"); producer.send(message); ``` 3. 接收消息 要从队列接收消息,可以使用消费者(Consumer)。消费者可以从队列接收消息,如下所示: ``` MessageConsumer consumer = session.createConsumer(queue); Message message = consumer.receive(); if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText(); System.out.println("Received message: " + text); } ``` 4. 消息监听 如果需要持续接收消息,可以使用消息监听器(MessageListener)。消息监听器可以在有新消息到达队列时自动调用,如下所示: ``` MessageConsumer consumer = session.createConsumer(queue); consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText(); System.out.println("Received message: " + text); } } }); ``` 5. 事务处理 如果需要确保消息被成功接收,可以使用事务(Transaction)。事务可以确保消息被成功处理,如下所示: ``` Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); TextMessage message = session.createTextMessage("Hello World!"); producer.send(message); session.commit(); ``` 以上是Java消息队列的使用详解。通过消息队列,可以实现组件之间的异步通信和解耦,从而提高系统的可靠性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是王小贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值