设为首页 加入收藏

TOP

Scalaz(37)- Free :实践-DB Transaction free style(一)
2017-10-10 12:13:06 】 浏览:2868
Tags:Scalaz Free 实践 Transaction free style

  我一直在不断的提示大家:FP就是Monadic Programming,是一种特殊的编程风格。在我们熟悉的数据库编程领域能不能实现FP风格呢?我们先设计一些示范例子来分析一下惯用的数据库编程过程:

 1 import scalaz._  2 import Scalaz._  3 import scala.language.higherKinds  4 import scala.language.implicitConversions  5 import com.jolbox.bonecp.BoneCP  6 import com.jolbox.bonecp.BoneCPConfig  7 import java.sql.Connection  8 import java.sql.ResultSet  9 
10 object freedbtxns { 11 def getTutorId(courseId: Int, conn: Connection): Int = { 12   val sqlString = "select TUTOR from COURSES where ID=" + courseId 13   conn.createStatement().executeQuery(sqlString).getInt("ID") 14 } 15 def getTutorPay(courseId: Int, conn: Connection): Double = { 16   val sqlString = "select PAYAMT from COURSES where ID=" + courseId 17   conn.createStatement().executeQuery(sqlString).getDouble("PAYAMT") 18 } 19 def getStudentFee(courseId: Int, conn: Connection): Double = { 20   val sqlString = "select FEEAMT from COURSES where ID=" + courseId 21   conn.createStatement().executeQuery(sqlString).getDouble("FEEAMT") 22 } 23 def updateTutorPay(tutorId: Int, plusAmt: Double, conn: Connection): Unit = { 24   val sqlString = "update TUTORS set PAYABLE = PAYABLE+"+plusAmt.toString + " where ID=" + tutorId 25  conn.createStatement().executeUpdate(sqlString) 26 } 27 def updateStudentFee(studentId: Int, plusAmt: Double, conn: Connection): Unit = { 28   val sqlString = "update STUDENTS set DUEAMT = DUEAMT+"+plusAmt.toString + " where ID=" + studentId 29  conn.createStatement().executeUpdate(sqlString) 30 } 31 def findEmptySeat(courseId: Int, conn: Connection): Int = { 32   val sqlString = "select ID from SEATS where OCCUPIED='T' AND ID=" + courseId 33   conn.createStatement().executeQuery(sqlString).getInt("ID") 34 } 35 def updateSeatsStatus(seatId: Int, taken: Boolean, conn: Connection): Unit = { 36   val sqlString = "update SEATS set OCCUPIED ='"+taken.toString.toUpperCase.head + "' where ID=" + seatId 37  conn.createStatement().executeUpdate(sqlString) 38 }  

我这里模拟了一个培训学校内的一些业务。上面设计的是一些基本函数,可以分别对学员、导师、座位进行查询和更新。如果我们需要把更新工作放入事务处理(transaction)内的话我们可以这样做:

 1 def updateStudent(studentId: Int, courseId: Int): Unit = {  2    val config = new BoneCPConfig()  3    val bonecp = new BoneCP(config)  4    val conn = bonecp.getConnection()  5    conn.setReadOnly(false)  6    conn.setAutoCommit(false)  7  conn.rollback()  8    try {  9      val fee = getStudentFee(courseId, conn) 10  updateStudentFee(studentId,fee, conn) 11  conn.commit() 12    } catch { 13      case (e:Exception) => conn.rollback() 14    } finally { 15  conn.close() 16  } 17 } 18 def updateStudentAndSeat(studentId: Int, courseId: Int): Unit = { 19    val config = new BoneCPConfig() 20    val bonecp = new BoneCP(config) 21    val conn = bonecp.getConnection() 22    conn.setReadOnly(false) 23    conn.setAutoCommit(false) 24  conn.rollback() 25    try { 26      val fee = getStudentFee(courseId, conn) 27  updateStudentFee(studentId,fee, conn) 28      val seatId = findEmptySeat(courseId, conn) 29      updateSeatsStatus(seatId, true, conn) 30  conn.commit() 31    } catch { 32      case (e:Exception) => conn.rollback() 33    } finally { 34  conn.close() 35  } 36 }

马上可以发现在我们对这些函数在事务处理内进行组合使用时我们必须重新对事务处理进行设置,无法实现真正意义上的函数组合。如果我们认可FP风格的话,这里起码有两项弊处:一是源代码增加了大量的铺垫(boilerplate code),重复事务处理设置、二是每个更新函数都会产生副作用,换句话说就是这里那里都会有副作用影响,很难控制,这样就增加了程序的复杂程度,造成代码分析的困难。

我们希望达到的目标:

 1 /*
 2
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scala入门学习随笔 下一篇函数式非凡的抽象能力

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目