Java

如何处理数据库并发操作

1. 基本问题 假设项目的用户信息包括用户积分,现在需求是给用户增加积分。在Service层有一个方法addCredits负责执行增加积分的操作。 @Override @Transactional("fproxy") public void addCredits(User user, int number) { // user对象为已从数据库读出的用户信息 // 先调用user.getCredits()获取当前的用户积分,增加number数量后写入user对象中 user.setCredits(user.getCredits() + number); //

基于Spring、Hibernate实现通用Dao层

这两天又捡起来老司机的web端代码,需要增加一些新的功能,比如说充值卡(PrepaidCard)模块。在写Dao层的时候发现好麻烦呀,每个实体类都要写一个对应的Dao(还包括接口跟实现),而大部分Dao方法都是基本的增删查改操作(CRUD)。比如getById,save,update,count,query,delete。而这些基本操作的代码其实都是相差无几的,既然这样那我们是不是可以写一个BaseDao来实现基本操作,然后让其他Dao来继承他。 以我现在要写的PrepaidCard实体类为例: /** * 省略各种import **/ @Entity @Table(name = "fp_prepaid_card") public class PrepaidCard implements Serializable { private static final long

spring mvc给freemarker传全局的值

通常spring mvc通过model给freemarker view传值,这是一个局部的概念,针对的是每个页面。有时候,我们会想给整个freemarker传一些全局的值。比如网站的url前缀,比如静态资源的路径,这些值在每个页面几乎都会需要用到,但我们不可能在每个model中传递这些值。 我们可以通过FreeMarkerViewResolver来给freemarker模板设置全局的值。 <beans:bean id="freemarkerResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <!– 省略 –> <!– 传值给${request} –> <beans:property name="requestContextAttribute" value="request"/> <beans:property name="attributes"> <beans:props> <!–

在spring框架中发送邮件

spring封装了一个邮件发送类:org.springframework.mail.javamail.JavaMailSender,这个JavaMailSender底层实现依赖的是公开的JavaMail API。所以要让spring的JavaMailSender正常工作,就必须先导入JavaMail API的实现类,比如com.sun.mail:javax.mail。 发送的邮件有两种类型,一种是简单文本邮件,不支持html,即使邮件内容中出现html标签,对方邮箱收到邮件后显示的仍是原始文本;一种是富文本邮件,支持html,对方邮箱收到邮件后会解析html标签并渲染。 一、配置JavaMailSender <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="smtp.exmail.qq.com"/> <property name="port" value="25"/> <property name="username" value="your exmail name" />

关于三层架构及事务的异常处理

我的个人理解,在三层架构的开发模式中。 dao层 负责对数据库进行增删查改基本操作。比如新建一个用户信息,更新一个用户信息。 每个dao层的方法都必须是单元操作,即不允许多次读写数据库,因此无需在dao层加事务处理。 在dao层无需手动去处理异常,异常由系统自动抛出,在service层捕获。 service层 负责组合dao层方法来处理业务逻辑。比如处理用户A转账给用户B,就需要两次调用dao层方法,一次是减少用户A的账户、一个是增加用户B的账户,这种业务逻辑就必须放在service层。 service层负责捕获dao层的异常,并判断是否向上抛出异常,是否回滚事务,或者还是在service层就处理掉异常,给上层返回处理结果。 通常,对于简单的业务逻辑,可以在service捕获并处理异常,然后给上层action层返回处理结果(成功or失败)即可。如果涉及到的业务复杂,并且涉及到多次的dao层写入操作,就必须回滚事务。注意,使用spring的aop事务的话,要么是在service层抛出异常触发aop事务回滚,要么就得手动回滚事务。如果异常在service层被捕获并处理掉,是不会触发事务回滚的。 action层 复杂调用service层方法,并捕获service层的异常,给用户输出可读的信息。 无需事务处理。

小内存运行kafka

按照kafka的官方文档(http://kafka.apache.org/documentation.html#quickstart)试了一下,解压程序包后运行 $bin/zookeeper-server-start.sh config/zookeeper.properties &   结果一上来就报错,无法分配内存。 从错误输出来看,这个zookeeper-server要求申请536870912字节(512MB)内存 =。=#。。 日了狗了我的亚马逊主机总共才1GB物理内存而且还没建swap分区,free看了一下大概就剩200MB左右的可用内存。检查这个命令的两个文件,发现在zookeeper-server-start.sh中有个定义export KAFKA_HEAP_OPTS=”-Xmx512M -Xms512M”。上来就要jvm去申请512MB的最小空间,把这个Xms改成16M后zookeeper就启动正常了。 然后做下一步启动kafka-esrver $bin/kafka-server-start.sh config/server.properties & 同样遇到这个问题,修改kafka-server-start.sh中的Xms配置(这个更狠,要了1GB的初始内存) 重新启动kafka-server,这回又显示如下错误:OutOfMemoryError 这回是jvm已经启动,在kafka的程序内部分配内存时候出错了。看来除了在启动jvm前就申请了大内存,在kafka程序内部又申请了大内存。 先去检查作为启动参数的server.properties文件,里面关于size的配置都不大,不至于OutOfMemory。 再检查kafka的源码,定位到KafkaServer.scala的589行附近。

Spring的@Autowired与自动代理

我想Spring框架的优点,第一条应该就是Spring的依赖注入了吧。尤其@Autowired这个注解,甚至可以直接注解在私有成员变量上而不用去写setter方法。之前看《Spring实战》这书的时候,里面说autowired自动注入是byType的,当时一直以为就是byClass,就是根据变量的类类型,去Spring context中找这样类型的bean。但当我写Dao层、Service层代码的时候,发现情况根本不是这样的。 比如说我现有有一个BookmakerDao接口,以及接口的实现类BookmakerDaoHibernate,并用@Repository注解将实现类注解为Spring bean。 public interface BookmakerDao { /** * */ } @Repository public class BookmakerDaoHibernate implements BookmakerDao { /**

Entity的继承以及泛型Dao(二)

一、继承与泛型都是因为懒 接着先前的例子,我们已经把Odds1x2与OddsHandicap这两个实体类的共同属性抽离出来放在他们的抽象父类Odds中。那么接下来要做的就是实现实体类相应的Dao类型。最简单的实现方法就是每个Entity对应一个Dao,每个Dao内都要实现对Entity的增删查改操作,但实际上大部分的增删查改操作都是类似的,只是处理不同的Entity而已。为了少写些重复代码,我们有完全正当的理由写一个泛型Dao来实现这些基本的增删查改操作。 仍然以我们的Odds为例子,假设我们现在只需要实现一个功能,就是查找某场比赛的某种赔率。 public interface OddsDao <T> { /** * 获取所有与某场赛事相关的有效赔率 * @param matchId * @return */ List<T> getAllValidByMatchId(long matchId);

Scroll to Top