Skip to main content
 首页 » 编程设计

Java事务从入门到精通

2022年07月19日143zlslch

本文介绍在Java中事务概念,包括JDBC、JPA、JMS事务处理方式。本文主要讲解本地事务,不涉及分布式事务。理解本文后有助于理解Spring的事务处理机制。

1. 什么是事务

在Java中一般任务事务时一些列动作必须都成功完成。因此如果一个或多个动作失败,则所有其他动作必须回滚保持应用状态不变,必须确保应用状态整体性不受破坏。

事务可能涉及一个或多个资源,如数据库、消息队列。从而产生在事务下执行不同动作的方式。包括涉及独立的本地资源事务,亦或多个资源参与的全局事务。

2. 本地资源事务

我们将首先探讨如何在处理单个资源时使用Java事务。这里可能对一个资源(如数据库)执行多个独立的动作,但这些动作须作为整体执行,就如单个工作单元。也就是说,这些动作在一个事务中。

在java中有多种方式访问和操作数据库资源。因此,处理对应事务方式也不同。本节我们学习java中最常用的库如何处理事务。

JDBC

Java Database Connectivity (JDBC) 是Java定义如何访问数据库的API。不同数据库厂商提供JDBC驱动程序以与厂商无关的方式连接到数据库。这样从驱动程序中获取连接可以对数据库执行不同的操作。

JDBC让我们可选地使用事务执行语句,缺省连接行为是auto-commit。即每单个语句执行后立刻被作为一个事务自动提交。但如果我们希望捆绑多个语句在单个事务中,需要改变默认行为进行实现:

Connection connection = DriverManager.getConnection(CONNECTION_URL, USER, PASSWORD); 
try { 
    connection.setAutoCommit(false); 
    PreparedStatement firstStatement = connection .prepareStatement("firstQuery"); 
    firstStatement.executeUpdate(); 
    PreparedStatement secondStatement = connection .prepareStatement("secondQuery"); 
    secondStatement.executeUpdate(); 
    connection.commit(); 
} catch (Exception e) { 
    connection.rollback(); 
} 

首先禁用连接的auto-commit方式。因此可以手工定义事务边界并执行提交或回滚。JDBC还支持设置Savepoint,用于控制回滚哪些语句。

JPA

Java Persistence API (JPA) 是Java规范,用来在面向对象领域模型和关系数据库系统之间架起一座桥梁。一些JPA的实现包括Hibernate、EclipseLink和iBatis等。

JPA可以定义普通类实体作为持久化标识类。EntityManager类提供必要接口与多个实体在持久化上下文中一起工作,持久化上下文可理解为管理实体的一级缓存。

持久化上下文有两者类型:事务作用域或扩展作用域。事务作用域的持久上下文绑定到单个事务。而扩展作用域的持久性上下文可以跨多个事务。持久性上下文的默认作用域是事务作用域。

下面示例看如何创建EntityManager,手动定义事务边界:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa-example"); 
EntityManager entityManager = entityManagerFactory.createEntityManager(); 
try { 
    entityManager.getTransaction().begin(); 
    entityManager.persist(firstEntity); 
    entityManager.persist(secondEntity); 
    entityManager.getTransaction().commit(); 
} catch (Exceotion e) { 
    entityManager.getTransaction().rollback(); 
} 

这里我们从EntityManagerFactory在事务作用域持久上下文中创建EntityManager。然后我们用begin、commit和rollback方法定义事务边界。

JMS

Java Messaging Service (JMS) 是Java规范,它允许应用程序使用消息进行异步通信。该API允许我们创建、发送、接收和读取来自队列或主题的消息。有几种消息传递服务符合JMS规范,包括OpenMQ和ActiveMQ。

JMS API支持在单个事务中绑定多个发送或接收操作。但基于消息集成体系结构的性质,消息的生产和使用不能是同一事务的一部分。事务的范围保持在客户端和JMS提供者之间:

JMS允许从特定供应商的ConnectionFactory创建连接会话。我们可以选择是否创建带事务处理的会话。对于非事务会话,我们还可以进一步定义一个适当的确认模式。

下面示例创建事务会话在一个事务中发送多个消息:

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(CONNECTION_URL); 
Connection connection = = connectionFactory.createConnection(); 
connection.start(); 
try { 
    Session session = connection.createSession(true, 0); 
    Destination = destination = session.createTopic("TEST.FOO"); 
    MessageProducer producer = session.createProducer(destination); 
    producer.send(firstMessage); 
    producer.send(secondMessage); 
    session.commit(); 
} catch (Exception e) { 
    session.rollback(); 
} 

这里针对主题类型Destination创建MessageProducer,从之前创建的会话中获取Destination,进一步使用会话定义事务边界,利用commit和rollback方法。

3. 总结

本文介绍Java事务概念,以及如何对数据库资源的JDBC和JPA操作方式控制事务,对消息服务资源JMS控制事务。掌握本文后可继续学习Spring事务以及分布式事务的多种实现方式,包括全局模式、尽力而为模式、幂等操作等,后续继续完善。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/115802886
阅读延展