博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软件事务内存导论(六)配置Akka事务
阅读量:6251 次
发布时间:2019-06-22

本文共 2855 字,大约阅读时间需要 9 分钟。

配置Akka事务

默认情况下,Akka为其相关的运行参数都设定了默认值,我们可以通过代码或配置文件akka.conf来更改这些默认设置。如果想了解如何指定或修改该配置文件位置的详细信息,请参阅Akka的文档。

针对单个事务,我们可以利用TransactionFactory在程序代码中更改其设置。下面就让我们用这种方式先后在Java和Scala中更改一些设置来为你展示如何实现设置的变更。

在Java中对事务进行配置

01 public  class  CoffeePot  {
02     private  static  final  Ref<Integer>  cups  =  new  Ref<Integer>(24);
03     public  static  int  readWriteCups(final  boolean  write)  {
04         final  TransactionFactory  factory  =
05         new  TransactionFactoryBuilder().setReadonly(true).build();
06         return  new  Atomic<Integer>(factory)  {
07             public  Integer  atomically()  {
08                 if(write)  cups.swap(20);
09                 return  cups.get();
10             }
11         }.execute();
12     }

为了能够用编程的方式对事务进行配置,我们需要一个TransactionFactory实例对象,而TransactionFactoryBuilder则为我们提供了很多方便的函数用于创建该Factory。在上例中,我们创建了一个TranactionFactoryBuilder实例对象,并调用该对象的setReadonly()函数来为TransactionFactory添加readonly选项。由于TransactionFactoryBuilder实现了Cascade设计模式,所以我们可以将更多用于改变事务属性的函数串在一起挂在TransactionFactoryBuilder构造函数之后、build()函数之前。随后我们把factory的实例对象作为Atomic的一个构造函数参数传给它,这样就保证了该事务内的所有操作都不会变更任何托管引用。

通过上述设置我们已经将readWriteCups()变成了一个只读事务,接下来你肯定希望了解在一个只读事务中试图改变引用的值将会产生什么后果。下面我们会调用两次readWriteCups(),第一次仅仅是读取cups引用的内容,而第二次调用则会尝试改变cups引用的值。

01     public  static  void  main(final  String[]  args)  {
02         System.out.println("Read  only");
03         readWriteCups(false);
04         System.out.println("Attempt  to  write");
05         try  {
06             readWriteCups(true);
07         catch(Exception  ex)  {
08             System.out.println("Failed  "  +  ex);
09         }
10     }
11 }

由于被设置成了只读,所以readWriteCups()事务不欢迎变更请求。于是当我们试图更改cups引用的值时,系统抛出了org.multiverse.api.exceptions.ReadonlyException异常,并且整个事务也将回滚。

Read  onlyAttempt  to  writeFailed  org.multiverse.api.exceptions.ReadonlyException:Can't  open  for  write  transactional  object  'akka.stm.Ref@1272670619'because  transaction  'DefaultTransaction'  is  readonly'

上述运行时异常是在调用引用的swap()的时候抛出来的。该函数的作用是当且仅当新值与当前值不同时,将其引用改为指向新值的地址;否则,该函数将忽略变更请求。所以在本例中,如果我们在调用swap()时将参数20换成与当前cpus引用的值相等的24,则系统就不会抛出任何异常。

在Scala中对事物进行配置

在Scala中,我们可以使用atomic()函数代替Atomic类来创建事务,该函数在使用时需要一个TransactionFactory类型的可选参数。同时,由于我们能够在伙伴对象(companion object)上使用工厂方法,所以创建factory实例也比在Java中要简单许多。

01 object  CoffeePot  {
02     val  cups  =  Ref(24)
03     def  readWriteCups(write  :  Boolean)  =  {
04         val  factory  =  TransactionFactory(readonly  =  true)
05         atomic(factory)  {
06             if(write)  cups.swap(20)
07             cups.get()
08         }
09     }
10     def  main(args  :  Array[String])  :  Unit  =  {
11         println("Read  only")
12         readWriteCups(false)
13         println("Attempt  to  write")
14         try  {
15             readWriteCups(true)
16         catch  {
17             case  ex  =>  println("Failed  "  +  ex)
18         }
19     }
20 }

除了在代码方面保持了Scala和Akka特有的简洁优雅之外,上述代码与Java版本就没有什么其他不同之处了,所以代码的执行结果也毫无意外地和Java版本完全相同。

Read  onlyAttempt  to  writeFailed  org.multiverse.api.exceptions.ReadonlyException:Can't  open  for  write  transactional  object  'akka.stm.Ref@1761506447'because  transaction  'DefaultTransaction'  is  readonly'

[1]近些年来,特别是随着JVM上新语言的不断涌现,由Kent Beck所著的《Smalltalk Best Practice Patterns》[Bec96]一书中所讨论的一些设计模式又被重新发掘了出来。

转载地址:http://ggfsa.baihongyu.com/

你可能感兴趣的文章
ArcSDE for Oracle表空间管理——暂时(TEMP)表空间
查看>>
Android Bundle类
查看>>
[转]IC行业的牛人
查看>>
linux 16进制 产看文件
查看>>
javaScript事件(四)event的公共成员(属性和方法)
查看>>
Oracle之比较NVARCHAR2字符串
查看>>
linux系统常用命令
查看>>
用原始方法解析复杂字符串,json一定要用JsonMapper么?
查看>>
Linux ld命令
查看>>
在 Word 中的受支持的区域设置标识符的列表
查看>>
No package的问题解决
查看>>
【转】chrome浏览器的跨域设置——包括版本49前后两种设置
查看>>
母牛的故事
查看>>
Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明2
查看>>
javaScript基础练习题-下拉框制作
查看>>
基于 OAuth 安全协议的 Java 应用编程1
查看>>
使用Golang利用ectd实现一个分布式锁
查看>>
javaweb学习总结五(内省、beanUtils工具包)
查看>>
An easy to use android color picker library
查看>>
iOS10全新推送功能的实现
查看>>