How to design global distributed transaction(none database)? Can JTA use for none db transaction?

前端 未结 3 2128
刺人心
刺人心 2020-12-13 11:00

I think this is a fairly common question: how to put my business logic in a global transaction in distributed systems environment? Cite an example, I have a TaskA containing

相关标签:
3条回答
  • 2020-12-13 11:15

    If you want to write your own transactional resource, you indeed need to implement an XAResource and let it join an ongoing transaction, handle prepare and commit requests from the transaction manager etc.

    Datasources are the most well known transactional resources, but as mentioned they are not the only ones. You already mentioned JMS providers. A variety of Caching solutions (e.g. Infinispan) are also transactional resources.

    Implementing XAResources and working with the lower level part of the JTA API and the even lower level JTS (Java Transaction Service) is not a task for the faint of heart. The API can be archaic and the entire process is only scarcely documented.

    The reason is that regular enterprise applications creating their own transactional resources is extremely rare. The entire point of being transactional is to do an action that is atomic for an external observer.

    To be observable in the overwhelming majority of cases means the effects of the action are present in a database. Nearly each and every datasource is already transactional, so that use case is fully covered.

    Another observable effect is whether a message has been send or not, and that too is fully covered by the existing messaging solutions.

    Finally, updating a (cluster-wide) in memory map is yet another observable effect, which too is covered by the major cache providers.

    There's a remnant of demand for transactional effects when operating with external enterprise information systems (EIS), and as a rule of thumb the vendors of such systems provide transaction aware connectors.

    The shiver of use cases that remain is so small that apparently nobody ever really bothered to write much about it. There are some blogs out there that cover some of the basics, but much will be left to your own experimentation.

    Do try to verify for yourself if you really absolutely need to go down this road, and if your need can't be met by one of the existing transactional resources.

    0 讨论(0)
  • 2020-12-13 11:22

    You're right, you need two-phase commit support thanks to a XA transaction manager provided by the JTA API.

    As far as I know Spring does not provide a transaction manager implementation itself. The JtaTransactionManager only delegates to existing implementation usually provided from JavaEE implementations.

    So you will have to plugin a JTA implementation into Spring to get effective job done. Here are some proposals:

    • JOTM
    • JBossTS based on Arjuna.
    • Atokimos

    Then you will have to implement your resource manager to support two-phase commit. In the JavaEE worlds, it consists in a resource adapter packaged as a RAR archive. Depending on the type of resource, the following aspects are to read/implement:

    • XAResource interface
    • JCA Java Connector Architecture mainly if a remote connection is involved
    • JTS Transaction Service if transaction propagation between nodes is required

    As examples, I recommend you to look at implementations for the classical "transactions with files" issue:

    • the transactional file manager from JBoss Transactions
    • XADisk project
    0 讨论(0)
  • 2020-12-13 11:28

    You could do the following (similar to your checkpoint strategy):

    1. TaskA executes in a (local) JTA transaction and tries to reserve the necessary resources before it delegates to your subtasks

    2. Subtask invocations are done via JMS/XA: if step 1 fails, no subtask will ever be triggered and if step 1 commits then the JMS invocations will be received at each subtask

    3. Subtasks (re)try to process their invocation message with a JMS max redelivery limit set (see your JMS vendor docs on how to do this)

    4. Configure a "dead letter queue" for any failures in 3.

    This works, assuming that:

    -retrying in step 3 makes sense

    -there is a bit of human intervention needed for messages in the dead letter queue

    If this is not acceptable then there is also TCC: http://www.atomikos.com/Main/DownloadWhitepapers?article=TccForRestApi.pdf - this can be seen as a "reservation" pattern for REST services.

    Hope this helps

    Guy

    http://www.atomikos.com

    0 讨论(0)
提交回复
热议问题