`
qqdwll
  • 浏览: 136730 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java 事务模型和策略

阅读更多
       Java中, 对于事务模式, 一般总结为三种。 本地事务, 编程式事务和声明事务。 下面, 我们就分别谈谈这三种事务模式。
      
     事务的ACDI 
事务有atomicity, consistancy, isolation and durability.

原子性, 事务在一个单元操作中, 要么提交, 要么回滚。有时候, 我们把它叫做LUW(logic unit of work)或者 SUW(single unit of work).

一致性, 事务在原子操作中, 永远不会处于非一致性的状态。 即在每次的原子事务中的insert, update, or delete, 都会拥有一致性的检查, 尽管事务还没有提交。

隔离性, 它表示不同的事务之间互相作用的程度。 ACDI属性, 决定了怎样保护我更新的那些资源, 而这些资源其它的事务也可以访问。 随着隔离性的提高, 一致性增强了而并发性减弱了。

持久性, 就是提交到数据库, 或者JMS更新到server的数据, 都会持久保存下来。

JTA and JTS

Java 开发中, 有效的管理事务, 并不需要知道 JTA(java transaction service)的后台处理。 但是, 理解java中分布式事务的限制是很重要的。

不管你用什么框架, 很多的企业应用, 都借助JTA(java transaction API)管理事务. JTA是开发者管理事务的接口。 JTS呢, 就是JTA下面的服务, 就像是JDBC和数据库driver之间的关系。  JTA的实现, 可以是商用服务器, 也可以使开源的服务器 (jboss)。 因为JTA必须支持JTS和非JTS实现,

UserTransaction Interface 
这个接口, 只在编程式事务中使用, 一般关注它的四个方法:
  • begin()
  • commit()
  • rollback()
  • getStatus()

这几个方法干嘛的。 就不用说了。

TranscationManager Interface
它主要用于声明式事务中, 在编程事务中, 我们也可以用它做UserTranscation的动作。 但最好在需要使用suspend和resume时, 用TransactionManager.

javax.transaction.TransactionManager.suspend()
在申明式或编程事务中, 把当前线程相关的事务suspend。 这个方法返回当前事务或者null.

javax.transaction.TransactionManager.resume()
它用于恢复上面暂停的事务。

Status Interface
方法UserTransaction.getStatus()可以获得 Status Interface。 它可以从当前事务中获得很多的信息。 它有下面的一些 value:
  • STATUS_ACTIVE
  • STATUS_COMMITTED
  • STATUS_COMMITTING
  • STATUS_MARKED_ROLLBACK
  • STATUS_NO_TRANSACTION
  • STATUS_PREPARED
  • STATUS_PREPARING
  • STATUS_ROLLEDBACK
  • STATUS_ROLLING_BACK
  • STATUS_UNKNOWN


对于开发人员来说, 特别重要的是STATUS_ACTIVE , STATUS_MARKED_ROLLBACK和STATUS_NO_TRANSACTION。  下面会更加详细的介绍他们。

STATUS_ACTIVE
很多时候, 需要检查当前线程是否绑定了事务, 来进行进一步的查询或处理。 例如:
...
if (txn.getStatus() == Status.STATUS_ACTIVE)
logger.info("Transaction active in query operation");
...


STATUS_MARKED_ROLLBACK
在申明事务中, 这个状态很有用。 为了性能的考虑, 我们也许需要跳过一些处理, 如果事务被前面的方法回滚后。

...
if (txn.getStatus() == Status.STATUS_MARKED_ROLLBACK)
throw new Exception(
"Further Processing Halted Due To Txn Rollback");
...


STATUS_NO_TRANSACTION
这是唯一的一个方法确定上下文中没有事务。

...
if (txn.getStatus() == Status.STATUS_NO_TRANSACTION)
throw new Exception(
"Transaction needed but none exists");
...

我们不能用STATUS_ACTIVE去判断是否没有事务。 事务还可能是其他的状态。

本地事务
本地事务, 其实就是DBMS或者JMS提供的事务管理。对于开发人员, 在本地事务中, 我们不用管理transactions, 而是 connections. 下面的代码说明了这个问题:

public void updateTradeOrder(TradeOrderData order)
throws Exception {
DataSource ds = (DataSource)
(new InitialContext()).lookup("jdbc/MasterDS");
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
String sql = "update trade_order ... ";
try {
stmt.executeUpdate(sql);
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
} finally {
stmt.close();
conn.close();
}
}


在上面的例子中, 我们使用connection的提交, 回滚。 那个自动提交开关, 告诉DBMS是否在执行每条SQL后立刻提交。 这个开关, 默认是true.

在spring 框架中, 用底层的JDBC的话,可以使用org.springframework.jdbc.datasource.DataSourceUtils. 例如:

public void updateTradeOrder(TradeOrderData order)
throws Exception {
Connection conn = DataSourceUtils
.getConnection(dataSource);
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
String sql = "update trade_order ... ";
try {
stmt.executeUpdate(sql);
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
} finally {
stmt.close();
conn.close();
}
}


在spring 中, datasource 及相关的类, 可以在配置文件中定义为:

<bean id="datasource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MasterDS"/>
</bean>
<bean id="TradingService"
class="com.trading.server.TradingService">
<property name="dataSource">
<ref local="datasource"/>
</property>
</bean>



Auto Commit and Connection Management
自动提交, 在本地事务中是很重要的。 通过collection 传递,还是可以处理复杂点的逻辑的, 例如:

public void updateTradeOrder(TradeOrderData order)
throws Exception {
DataSource ds = (DataSource)
(new InitialContext()).lookup("jdbc/MasterDS");
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
OrderDAO orderDao = new OrderDAO();
TradeDAO tradeDao = new TradeDAO();
try {
//SQL and Connection Logic in DAO Classes
orderDao.update(order, conn);
tradeDao.update(order, conn);
conn.commit();
} catch (Exception e) {
logger.fatal(e);
conn.rollback();
throw e;
} finally {
conn.close();
}
}



这种方式, 在大多数情况下是可以工作的, 但这不是一个好的事务策略, 它需要大量的代码维护, 如果你需要类似上面的代码逻辑的话, 那你就应该使用编程事务或者申明事务了。

本地事务的考虑和限制
本地事务, 只能处理简单的逻辑, 如果系统需要复杂的处理, 对于应用架构, 这个模式会有一些危险的限制。

第一个地方, 就是在coding时候, 开发人员在很多地方容易犯错。开发人员需要时刻注意关掉自动提交功能。 在次, 如果许多方法有管理连接, 我们在调用这些方法的时候, 也要格外小心。 除非我们的应用基本上都是单表操作。 否则, 没有办法保证所以的SQL都在同一个事务中。

还有一个问题, 在使用XA global transaction时候, 本地事务不能存在并发。 当协调多个资源时候, 比如数据库和JMS destination的时候, 我们不能使用本地事务和确保ACDI属性。

基于上面的限制, 本地事务只能在简单的应用和单表操作中使用。

编程事务模型
编程事务于本地事务的最大不同, 就是开发者管理 transactions, 而不是 connections. 下面是个EJB中使用的场景:
public void updateTradeOrder(TradeOrderData order)
throws Exception {
UserTransaction txn = sessionCtx.getUserTransaction();
txn.begin();
try {
TradeOrderDAO dao = new TradeOrderDAO();
dao.updateTradeOrder(order);
txn.commit();
} catch (Exception e) {
log.fatal(e);
txn.rollback();
throw e;
}
}


从上面的代码我们可以看到, 事务被传播到TradeOrderDAO对象中, 但不同于本地模型, TradeOrderDAO不再需要管理transcations 或者 connections. 它所需要做的, 就是从连接池中拿出连接并释放。

在编程事务中, 开发者需要开启和终于一个事务。 在EJB中, 这个通过UserTransaction接口实现, 在spring 中, 通过TransactionTemplate或者PlatformTransactionManager实现。

然后, 调用begin(), commit() 或者rollback()方法。

尽管编程事务模型常常不被鼓励使用, 但在一些场合下, 它确实挺有用的。下面的例子是在spring中使用情形:

public void updateTradeOrder(TradeOrderData order)
throws Exception {
transactionTemplate.execute(new TransactionCallback()
{
public Object doInTransaction(
TransactionStatus status)
{
try {
TradeOrderDAO dao = new TradeOrderDAO();
dao.updateTradeOrder(order);
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
}
} );
}
<bean id="transactionTemplate"
class="org.springframework.transaction.support.
TransactionTemplate">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
</bean>
<bean id="tradingService"
class="com.trading.server.TradingService">
<property name="transactionTemplate">
<ref local="transactionTemplate"/>
</property>
</bean>


从上面的例子看出, 使用框架, 并不需要调用begin(), commit()方法。

Obtaining a Reference to the JTA UserTransaction

在基于web应用中, 需要使用JNDI查找获得。例如:
...
InitialContext ctx = new InitialContext()
UserTransaction txn = (UserTransaction)
ctx.lookup("javax.transaction.UserTransaction")
...


说到这, 这情况变得有点复杂了。 我们知道, 上面的事务通过jndiI绑定到服务器上。 有写服务器在外部不能获得JNDI resouce ( web container. like tomcat). 但有些是可以的(Jboss). 下面的列出一些常见的绑定的transaction.

JBoss: "UserTransaction"
WebLogic: "javax.transaction.UserTransaction"
WebSphere v5+: "java:comp/UserTransaction"
WebSphere v4: "jta/usertransaction"
SunONE: "java:comp/UserTransaction"
JRun4: "java:comp/UserTransaction"
Resin: "java:comp/UserTransaction"
Orion: "java:comp/UserTransaction"
JOnAS: "java:comp/UserTransaction"


上面的UserTransaction, 在容器外,往往不能获得,但在单元测试或者基于Swing的应用中, 我们怎么解决这个问题呢。 这时候, 我们需要通过Class.forName()方法加载服务端指定的TransactionManagerFactory类, 这样, 才能启动和停止一个事务。 下面的代码演示使用IBM Websphere TransactionManagerFactory:

...
//load the transaction manager factory class
Class txnClass = Class.forName(
"com.ibm.ejs.jts.jta.TransactionManagerFactory");
//using reflection invoke the getTransactionManager()
//method to get a reference to the transaction manager
TransactionManager txnMgr = (TransactionManager)
txnClass.getMethod("getTransactionManager",null)
.invoke(null, null);
//start the transaction via the transaction manager
txnMgr.begin();
...


我们可以用任何服务器的TransactionManagerFactory类替换掉上面的object. 这样我们可以在容器外拿到事务管理实例了。

在编程事务中,我们要特别注意异常处理。 看看下面的代码, 我们只处理checked 异常:

public void updateTradeOrder(TradeOrderData order)
throws Exception {
UserTransaction txn = sessionCtx.getUserTransaction();
txn.begin();
try {
TradeOrderDAO dao = new TradeOrderDAO();
dao.updateTradeOrder(order);
txn.commit();
} catch (ApplicationException e) {
log.fatal(e);
txn.rollback();
throw e;
}
}


编程事务, 说明开发者要自己处理异常。特别注意且确保要关掉事务 (这在大大复杂项目中, 是件很难的事情:)。

编程事务使用场景
一般, 不鼓励使用编程事务, 但在一些场合中, 编程事务还是很有用的。 特别是事务是客户端发起的。 客户端需要调用多个 EJBbean时候,这是就需要在客户端使用它。 但要注意, ejb端需要使用申明事务, 因为编程事务不能在不同的bean之间传递。

另外一个场景就是, 因为JTA事务是比较耗资源的, 为了性能的需求, 我们需要在一些地方关掉事务, 比如银行系统。 只在转账的时候打开事务, 在加载, 验证数据的时候关掉事务。 而这个在申明事务中很难做到, 因为申明事务没有编程控制, 不知道什么时候事务开始和结束。 

编程事务, 只有在你有好的理由需要使用的时候才使用它。 否则的话, 你就要用到申明事务。

申明事务模型
经过前面的介绍, 我们知道, 编程事务需要开发人员启动, 提交和回滚事务。 那么, 申明事务,容器管理着事务, 就不需要开发人员写Java代码去启动, 提交一个事务了。但是, 开发人员必须告诉容器, 怎样管理事务。 在spring 中, 通过ApplicationContext.xml bean配置文件实现。

在Spring中, 我们通过TransactionProxyFactoryBean代理使用申明事务。 例如:

<bean id="tradingServiceTarget"
class="com.trading.server.TradingServiceBean">
...
</bean>
<bean id="tradingService"
[b]class="org.springframework.transaction.interceptor.
TransactionProxyFactoryBean"[/b]>
<property name="transactionManager" ref="txnMgr"/>
<property name="target" ref="tradingServiceTarget"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_SUPPORTS</prop>
<prop key="update*">
PROPAGATION_REQUIRED,[b]-Exception[/b]
</prop>
</props>
</property>
</bean>


配置文件中的-Exception, 表示遇到任何Exception都会回滚。 一般我们会指定一个特定的checked异常。

Transaction Attributes

容器, 通过Transaction Attributes, 知道怎样管理JTA事务。 一共有六个属性设置。 前面是EJB, 后面是Spring。
  • Required        PROPAGATION_REQUIRED
  • Mandatory     PROPAGATION_MANDATORY
  • RequiresNew  PROPAGATION_REQUIRES_NEW
  • Supports        PROPAGATION_SUPPORTS
  • NotSupported PROPAGATION_NOT_SUPPORTED
  • Never              PROPAGATION_NEVER
  •                         PROPAGATION_NESTED (only spring. not EJB)


要是使用PROPAGATION_NESTED, 后台的JTS必须能够支持事务的嵌套。

REQUIRED
必须使用, 上下文中没有的话, 需要创建一个新的事务。

MANDATORY
它表示需要一个事务, 但不像REQUIRED, 它不会创建一个新的事务。 如果上下文中没有事务, 就会抛出TransactionRequiredException。 表示需要的事务不存在。

REQUIRESNEW
它表示需要一个新的事务, 如果上下文中已经有了事务。 前面的事务就会挂起。 但这个新的事务终止的时候, 前面的事务会resumed。 这个特性违反ACDI属性 (如果前面存在事务时候)。 如果一个操对于外面的事务, 需要独自先完成时, 它是很有用的。比如, 记录log. 这个log会把前面的操作记录下来, 无论这前面的操作是成功或者失败。 如果不用这个特性, 记录log的操作, 在前面逻辑操作失败的情况下跟着回滚。 这就不符合任何操作都需要记录的理念了。

SUPPORTS
表示可以不需要事务, 但上下文中如果存在的话, 会使用前面的事务。

NOTSUPPORTED
这个表示不使用事务。 如果前面存在事务, 事务会被挂起然后等待这方法完成。这个常在那些方法可能会有异常的地方使用。

NEVER
跟notsupported不同, 如果前面有事务的话, 会抛出异常。
这个属性, 会导致不可预知或runtime exception. 所以慎重使用。

在Spring中,我们可以使用TransactionAttributeSource或者TransactionProxyFactoryBean. 下面分别演示这两种方法:

使用  TransactionAttributeSource
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="*">PROPAGATION_MANDATORY</prop>
</props>
</property>
</bean>
<bean id="tradingService"
class="org.springframework.transaction.interceptor.
TransactionProxyFactoryBean">
<property name="transactionAttributeSource">
<ref local="transactionAttributeSource">
</property>
...
</bean>


使用 TransactionProxyFactoryBean

<bean id="tradingService"
class="org.springframework.transaction.interceptor.
TransactionProxyFactoryBean">
<property name="transactionManager" ref="txnMgr"/>
<property name="target" ref="tradingServiceTarget"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_MANDATORY</prop>
</props>
</property>
</bean>


对事务的属性, 一个相关的问题就是,在方法上指定属性, 而不是在类上。但一个好的方法应该是在类上定义属性, 对个别方法进行调整。  也是类上定义的, 是大多数方法都试用的。

例如 :

<bean id="tradingService" ...>
...
<property name="transactionAttributes">
<props>
[b]<prop key="*">PROPAGATION_MANDATORY</prop>
<prop key="getAllTradersByID">
PROPAGATION_SUPPORTS
</prop>[/b]
</props>
</property>
</bean>



Required vs. Mandatory
有些情况下, 不知道这两种属性使用哪一种。 这里给出个最佳实践:
如果一个方法,并不负责回滚, 那么这个方法就使用Mandatory

怎么理解呢, 用反推法。 这是因为遵循一个原子, 事务是哪里启动的, 就跟在哪里回滚。 如果这个方法使用了Required。就会创建一个新的事务。 就永远不会回滚了。

事务隔离级别

对开发人员来说, 另外一个对事务的设定,就是隔离级别。 这个属性的设定, 依赖于服务器和数据库。服务器也许支持许多的隔离级别设定, 但数据库必须也要支持才能起效。  它的设定, 需要在一致性与并发性之间取个折中或者看业务需求。 这里介绍EJB和Spring支持的四种隔离级别。

  •   TransactionReadUncommitted
  •   TransactionReadCommitted  
  •   TransactionRepeatableRead
  •   TransactionSerializable 


TransactionReadUncommitted
这是最低的一个级别, 它允许事务读取另外事务中未提交的更新数据。 这个违反基本的ACID, 许多数据库厂商都不支持(包括Oracle)。

TransactionReadCommitted
这个级别, 允许多个事务访问同一个数据。 但是他们之间的更新, 只有在提交后才能读取。 这个级别, 是默认的设置且大多数厂商都支持的。

TransactionRepeatableRead
可重复读, 既多个事务, 每次查询的结果都是一样的 (自己更改的不算,因为自己拥有读, 写锁)。 例如, 有两个事务, 有一个事务更改了数据并提交了。 另外一个事务, 在自己没有提交钱, 看到的仍然是自己开始取得的那个数据。 直到自己把事务提交后, 才知道林另外一个事务更改了数据。

TransactionSerializable
这个是最高的隔离级别。 表示同时只有一个事务才能访问数据 (但对于oracle, 事实并不是这样的)。 Oracle稍有不同, 一个事务访问数据时, 另一个事务并不会被挂起。但是, 另外一个事务试图去读取同一个数据, Oracle会返回Ora-08177错误消息。

现实中事务隔离级别的设置
在Spring中,隔离级别的设定, 伴随在transaction属性中。 例如:

<bean id="tradingService" ...>
...
<property name="transactionAttributes">
<props>
<prop key="placeTrade">
PROPAGATION_MANDATORY,ISOLATION_SERIALIZABLE
</prop>
</props>
</property>
</bean>


隔离级别的设定。 必须要数据库也支持, 如果数据不支持, 在数据库中会使用默认设置代替而不会抛出任何exception。 所以开发人员在设定时要注意这一点。 那当然最好是使用TransactionReadCommitted, 除非你有一个必要改变它。

XA Transaction Processing
XA接口在JTA事务中的重要性, 从异构系统中可以看出来。  例如:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void placeFixedIncomeTrade(TradeData trade)
throws Exception {
try {
...
Placement placement =
placementService.placeTrade(trade);
//JMS发送消息
placementService.sendPlacementMessage(placement);
//数据库执行更细
executionService.executeTrade(placement);
} catch (TradeExecutionException e) {
log.fatal(e);
sessionCtx.setRollbackOnly();
throw e;
}
}


在上面的代码中, 如果数据库执行发生exception, 但JMS消息还是会发送出去。尽管我们需要这个消息立刻被释放。 因为JMS是在一个非XA环境下的独立系统,这样就违反我们的ACDI了, 这时候, 我们需要一个全局的事务管理控制JMS和数据库。 使用X/Open XA interface, 我们可以把多个资源维护在ACDI下。 既两阶段提交。

什么时候使用XA
当有多个资源 (数据库和JMS)在同一个事务下时候, 才使用X/Open XA Interface。 























0
4
分享到:
评论

相关推荐

    Java事务设计策略.

    综上所述,Java事务设计策略涉及多种不同的事务模型和技术,每种模型和技术都有其适用场景和优势。理解这些基本概念和最佳实践对于构建健壮、可靠的企业级Java应用程序至关重要。开发者可以根据具体的应用需求和环境...

    java事务设计模式

    Java事务设计模式是复杂且至关重要的,开发者需要理解不同事务模型的适用场景,熟悉JTA提供的工具和接口,以及如何避免编程陷阱。正确地设计和实现事务处理,不仅可以确保数据的完整性和一致性,还能提高系统的可...

    Java事务设计模式_java_事务设计模式_

    本文将深入探讨Java中的事务设计策略,包括本地事务模型、编程式事务模型、声明式事务模型以及几种事务设计模式。 首先,我们来理解事务的基本概念。事务是数据库操作的基本单元,它保证了一组操作要么全部成功,...

    Java事物设计策略

    Java事务设计策略是Java开发中一个至关重要的主题,它直接影响着应用程序的数据完整性和并发性能。在深入探讨前,我们先明确几个核心概念:事务、ACID特性、JTA(Java Transaction API)、JTS(Java Transaction ...

    JavaTransaction

    2. 编程式事务模型:编程式事务模型利用Java事务API (JTA),使开发人员能够直接控制事务的开始、提交和回滚。通过UserTransaction接口,开发人员可以调用begin()、commit()和rollback()方法来管理事务。虽然这种方法...

    java 平台性能战术与策略 Java Platform Performance Strategies and Tactics.rar

    6. **数据库优化**:SQL查询优化、连接池管理、缓存策略(如使用Hibernate二级缓存)和事务管理,都是Java应用性能的关键因素。 7. **网络I/O优化**:使用NIO(Non-blocking I/O)可以提高处理大量并发连接的能力,...

    java MVC登陆模型

    Java MVC登录模型是一种常见的软件架构模式,用于构建可维护性和扩展性良好的Web应用程序。MVC全称为Model-View-Controller,即将模型(Model)、视图(View)和控制器(Controller)三个部分分离,以实现业务逻辑、...

    Java微服务系统分布式事务解决方案.docx

    ### Java微服务系统分布式事务解决方案 #### 一、CAP定理与分布式系统设计原则 **CAP理论**在分布式系统的设计中扮演着至关重要的角色。它指出,在分布式计算环境中,任何共享数据系统都无法同时保证一致性...

    分布式事务专题_java_分布式_

    12. **最佳实践**:在实际应用中,应根据业务场景选择合适的事务模型,同时考虑性能、可用性和可扩展性。对于低延迟和高并发的场景,可能需要牺牲部分一致性以换取更高的系统效率。 以上就是Java分布式服务开发中...

    多数据源分布式事务管理调研报告.zip

    在现代企业级应用中,随着业务复杂性和...综上所述,多数据源分布式事务管理是一项复杂的任务,需要深入理解各种事务模型、解决方案和最佳实践,以便在保证数据一致性的前提下,构建高效、可靠且可扩展的Java应用程序。

    多数据源事务解决方案,单应用多数据库保证事务

    总结起来,处理多数据源事务需要理解Spring的事务管理机制,包括PlatformTransactionManager接口、自定义注解和AOP的应用,以及事务的一致性模型。通过合理的配置和编程,可以有效地在单个应用程序中管理多数据源的...

    java面试八股文各类面试题

    理解其工作原理、消息模型、消费者模式和高可用性策略。 这些知识点通常会以八股文的形式出现,即从基本概念到高级特性的全面覆盖,旨在测试和提升候选人的综合技术能力。通过深入学习和实践这些领域的知识,你将为...

    2024 Java面试宝典合集

    3. **JAVA核心面试知识整理**:这部分内容可能涵盖Java基础,如内存模型、垃圾收集、类加载机制、多态、封装、继承、接口、异常处理、集合框架(List、Set、Map的区别和使用)、IO流、NIO、反射、枚举、注解等。...

    java 13 distributed programming and java

    企业级Java Beans(EJB)是Java EE中的服务器端组件模型,用于开发分布式、事务性的业务逻辑。EJB提供了一种简单的方式来实现复杂的业务逻辑,同时EJB容器为EJB组件提供了如安全性、事务管理、状态管理等服务。 ###...

    Java版精华帖java讨论

    - 内存模型和垃圾回收机制,了解GC的工作原理和调优策略。 8. **最新技术趋势**: - Java EE向Jakarta EE的转变,相关规范的更新和发展。 - Java在大数据、云计算、物联网(IoT)等领域的应用。 通过水木清华BBS...

    Java-25-通用设计-分布式事务-消息队列.rar

    分布式事务和消息队列在Java开发中是两个非常重要的概念,尤其在构建大规模、高并发、高可用的系统时更是不可或缺。本资料包"Java-25-通用设计-分布式事务-消息队列.rar"主要涵盖了这两个主题,下面将详细阐述它们的...

    用Java实现的SQL数据库系统

    这样的系统通常包括数据模型、查询解析器、事务管理器和存储引擎等核心组件。 1. **数据模型**:数据模型是数据库设计的基础,常见的有关系型数据模型(如SQL所基于的)、对象-关系模型和NoSQL模型。在Java实现的...

    JAVA面试32问

    1. **Java内存模型**:Java内存模型(JMM)规定了线程如何共享和访问内存,包括堆、栈、方法区、本地方法栈等区域。理解JMM有助于解决并发中的数据一致性问题。 2. **垃圾回收(GC)**:Java的自动内存管理机制,...

    Thinking in Enterprise Java.rar

    12. **测试和部署**:包括单元测试、集成测试、持续集成、部署到应用服务器的策略和配置等。 通过学习《Thinking in Enterprise Java》,开发者将能够全面理解和运用Java EE的各个方面,为构建复杂的企业级应用打下...

Global site tag (gtag.js) - Google Analytics